Paso 5 (1)- Trayectorias de hospitalización y mortalidad con foco en condiciones vinculadas a trastornos de salud mental y consumo de sustancias posterior a un primer ingreso por alguno de estos trastornos, en usuarios/as jóvenes y adultos emergentes de población general y pertenecientes a pueblos originarios, 2018-2021, Chile

Representar las mejores opciones de agrupamiento, junto con su relación con otras variables. En esta etapa, analizamos la asociación con covariables de la solución con mejores índices de calidad para la resolución trimestral.

Autor/a

Andrés González Santa Cruz

Fecha de publicación

19 de may, 2025

Configurar

Código
# remover objetos y memoria utilizada
rm(list=ls());gc()
          used (Mb) gc trigger (Mb) max used (Mb)
Ncells  600295 32.1    1288718 68.9   779794 41.7
Vcells 1182808  9.1    8388608 64.0  1876026 14.4
Código
#remover imágenes
while(!dev.cur())dev.off()
cat("\014")
Código
# if(Sys.info()["sysname"]=="Windows"){
#  folder_path <- ifelse(dir.exists("H:/Mi unidad/PERSONAL ANDRES/UCH_salud_publica/asignaturas/un_inv_II/"),
#                        "H:/Mi unidad/PERSONAL ANDRES/UCH_salud_publica/asignaturas/un_inv_II/",
#                        "C:/Users/CISS Fondecyt/Mi unidad/Alvacast/SISTRAT 2022 (github)/_proposal_grant/2023/")
# } else {folder_path <- ""}
load(paste0(getwd(),"/","avance25011725_pre_25.RData"))

Paquetes estadísticos

Código
#elegir repositorio
if(Sys.info()["sysname"]=="Windows"){
  options(repos = c(CRAN = "https://cran.dcc.uchile.cl/"))
}
options(install.packages.check.source = "yes") # Chequea la fuente de los paquetes

#borrar caché
#system("fc-cache -f -v")

if(!require(pacman)){install.packages("pacman");require(pacman)}

pacman::p_unlock(lib.loc = .libPaths()) #para no tener problemas reinstalando paquetes

if(Sys.info()["sysname"]=="Windows"){
if (getRversion() != "4.4.1") { stop("Requiere versión de R 4.4.1. Actual: ", getRversion()) }
}

cat("quarto version: "); system("quarto --version") 
quarto version: 
[1] 0
Código
if(!require(job)){install.packages("job");require(job)}
if(!require(kableExtra)){install.packages("kableExtra");require(kableExtra)}
if(!require(tidyverse)){install.packages("tidyverse");require(tidyverse)}
if(!require(cluster)){install.packages("cluster"); require(cluster)}
if(!require(WeightedCluster)){install.packages("WeightedCluster"); require(WeightedCluster)}
if(!require(devtools)){install.packages("devtools"); require(devtools)}
if(!require(TraMineR)){install.packages("TraMineR"); require(TraMineR)}
if(!require(TraMineRextras)){install.packages("TraMineRextras"); require(TraMineRextras)}
if(!require(NbClust)){install.packages("NbClust"); require(NbClust)}
if(!require(haven)){install.packages("haven"); require(haven)}
if(!require(ggseqplot)){install.packages("ggseqplot"); require(ggseqplot)}
if(!require(grid)){install.packages("grid"); require(grid)}
if(!require(gridExtra)){install.packages("gridExtra"); require(gridExtra)}
if(!require(Tmisc)){install.packages("Tmisc"); require(Tmisc)}
if(!require(factoextra)){install.packages("factoextra"); require(factoextra)}
if(!require(stargazer)){install.packages("stargazer"); require(stargazer)}
if(!require(gtsummary)){install.packages("gtsummary"); require(gtsummary)}
if(!require(lmtest)){install.packages("lmtest"); require(lmtest)}
if(!require(emmeans)){install.packages("emmeans"); require(emmeans)}
if(!require(fpp2)){install.packages("fpp2"); require(fpp2)}
if(!require(purrr)){install.packages("purrr"); require(purrr)}
if(!require(forecast)){install.packages("forecast"); require(forecast)}
if(!require(magrittr)){install.packages("magrittr"); require(magrittr)}
if(!require(foreach)){install.packages("foreach"); require(foreach)}
if(!require(doParallel)){install.packages("doParallel"); require(doParallel)}
if(!require(progressr)){install.packages("progressr"); require(progressr)}
if(!require(chisq.posthoc.test)){devtools::install_github("ebbertd/chisq.posthoc.test")}
if(!require(rstatix)){install.packages("rstatix"); require(rstatix)}
if(!require(rio)){install.packages("rio"); require(rio)}
if(!require(cowplot)){install.packages("cowplot"); require(cowplot)}
if(!require(DiagrammeR)){install.packages("DiagrammeR"); require(DiagrammeR)}
if(!require(DiagrammeRsvg)){install.packages("DiagrammeRsvg"); require(DiagrammeRsvg)}
if(!require(rsvg)){install.packages("rsvg"); require(rsvg)}
if(!require(survminer)){install.packages("survminer"); require(survminer)}
if(!require(epitools)){install.packages("epitools"); require(epitools)}
if(!require(metafor)){install.packages("metafor"); require(metafor)}


seq_mean_t_dos_grupos <- function(bd = NULL, group1, group2) {
  # Agrupar por ambas variables
  resultados <- by(bd, list(group1, group2), seqmeant)
  
  # Obtener todas las combinaciones posibles de los grupos
  combinaciones <- expand.grid(group1 = unique(group1), group2 = unique(group2), stringsAsFactors = FALSE)
  
  # Extraer los resultados y asociarlos con las combinaciones
  resultados_df <- do.call(rbind, lapply(seq_along(resultados), function(i) {
    group_name1 <- attr(resultados, "dimnames")[[1]][i]
    group_name2 <- attr(resultados, "dimnames")[[2]][i]
    
    data.frame(factor_inclusivo_1 = group_name1, 
               factor_inclusivo_2 = group_name2, 
               Mean = resultados[[i]])
  }))
  
  # Unir los resultados con las combinaciones para rellenar los valores faltantes
  final_df <- merge(combinaciones, resultados_df, by.x = c("group1", "group2"), 
                    by.y = c("factor_inclusivo_1", "factor_inclusivo_2"), all.x = TRUE)
  
  return(final_df)
}

multinom_pivot_wider <- function(x) {
  # check inputs match expectatations
  # create tibble of results
  df <- tibble::tibble(outcome_level = unique(x$table_body$groupname_col))
  df$tbl <- 
    purrr::map(
      df$outcome_level,
      function(lvl) {
        gtsummary::modify_table_body(
          x, 
          ~dplyr::filter(.x, .data$groupname_col %in% lvl) |>
            dplyr::ungroup() |>
            dplyr::select(-.data$groupname_col)
        )
      }
    )
  
  tbl_merge(df$tbl, tab_spanner = paste0("**", df$outcome_level, "**"))
}

best_subset_multinom <- function(y, x.vars, data) {
  # y       Nombre de la variable dependiente (cadena de texto)
  # x.vars  Vector de nombres de predictores (caracter)
  # data    Dataframe con los datos de entrenamiento
  
  # Cargar las librerías necesarias
  require(dplyr)
  require(purrr)
  require(tidyr)
  require(nnet)
  require(MASS)
  
  # Generar todas las combinaciones posibles de predictores
  predictors_list <- lapply(1:length(x.vars), function(i) {
    combn(x.vars, i, simplify = FALSE)
  }) |> unlist(recursive = FALSE)
  
  # Inicializar una lista para almacenar los resultados
  results <- list()
  
  # Iterar sobre cada combinación de predictores
  for (i in seq_along(predictors_list)) {
    predictors <- predictors_list[[i]]
    formula <- as.formula(paste(y, "~", paste(predictors, collapse = "+")))
    
    # Ajustar el modelo multinomial
    model <- tryCatch(
      nnet::multinom(formula, data = data, trace = FALSE),
      error = function(e) NULL
    )
    
    # Si el modelo se ajustó correctamente, almacenar los resultados
    if (!is.null(model)) {
      # Extraer el AIC del modelo
      aic <- AIC(model)
      
      # Almacenar la información en una lista
      results[[length(results) + 1]] <- list(
        predictors = predictors,
        model = model,
        AIC = aic
      )
    }
  }
  
  # Convertir la lista de resultados en un dataframe
  results_df <- results |>
    purrr::map_df(function(res) {
      data.frame(
        predictors = paste(res$predictors, collapse = "+"),
        AIC = res$AIC,
        stringsAsFactors = FALSE
      )
    })
  
  # Ordenar los modelos por AIC de menor a mayor
  results_df <- results_df |> arrange(AIC)
  
  return(results_df)
}
best_subset_multinom_interactions <- function(y, x.vars, data) {
  # y       Nombre de la variable dependiente (cadena de texto)
  # x.vars  Vector de nombres de predictores (caracter)
  # data    Dataframe con los datos de entrenamiento
  
  # Cargar las librerías necesarias
  require(dplyr)
  require(purrr)
  require(tidyr)
  require(nnet)
  require(MASS)
  
  # Generar todas las combinaciones posibles de predictores (efectos principales)
  main_effects_list <- lapply(1:length(x.vars), function(i) {
    combn(x.vars, i, simplify = FALSE)
  }) |> unlist(recursive = FALSE)
  
  # Inicializar una lista para almacenar los resultados
  results <- list()
  
  # Iterar sobre cada combinación de efectos principales
  for (main_effects in main_effects_list) {
    
    # Generar términos de interacción de hasta 3 variables
    interaction_terms <- list()
    
    # Para interacciones de 2 variables
    if (length(main_effects) >= 2) {
      interaction_terms_2way <- combn(main_effects, 2, function(x) paste(x, collapse = ":"))
      interaction_terms <- c(interaction_terms, interaction_terms_2way)
    }
    
    # Para interacciones de 3 variables
    if (length(main_effects) >= 3) {
      interaction_terms_3way <- combn(main_effects, 3, function(x) paste(x, collapse = ":"))
      interaction_terms <- c(interaction_terms, interaction_terms_3way)
    }
    
    # Combinar efectos principales e interacciones
    all_terms <- c(main_effects, interaction_terms)
    
    # Generar todas las combinaciones posibles de términos (incluyendo interacciones)
    # Solo se incluyen interacciones si sus efectos principales están presentes
    term_combinations <- list()
    
    # Obtener todos los subconjuntos de efectos principales
    main_effects_subsets <- lapply(1:length(main_effects), function(i) {
      combn(main_effects, i, simplify = FALSE)
    }) |> unlist(recursive = FALSE)
    
    # Para cada subconjunto de efectos principales
    for (me in main_effects_subsets) {
      # Iniciar con los efectos principales
      terms <- me
      
      # Incluir interacciones solo si todos sus efectos principales están incluidos
      possible_interactions <- interaction_terms[
        sapply(interaction_terms, function(x) {
          vars_in_interaction <- unlist(strsplit(x, ":"))
          all(vars_in_interaction %in% me)
        })
      ]
      
      # Generar todas las combinaciones de interacciones para incluir
      interaction_subsets <- list(NULL)
      if (length(possible_interactions) > 0) {
        interaction_subsets <- lapply(1:length(possible_interactions), function(i) {
          combn(possible_interactions, i, simplify = FALSE)
        }) |> unlist(recursive = FALSE)
      }
      
      # Para cada combinación de interacciones, crear el conjunto completo de términos
      for (ints in interaction_subsets) {
        if (is.null(ints)) {
          full_terms <- terms
        } else {
          full_terms <- c(terms, ints)
        }
        
        # Añadir a la lista de combinaciones de términos
        term_combinations <- append(term_combinations, list(full_terms))
      }
    }
    
    # Ajustar modelos para cada combinación de términos
    for (terms in term_combinations) {
      formula <- as.formula(paste(y, "~", paste(terms, collapse = "+")))
      
      # Ajustar el modelo multinomial
      model <- tryCatch(
        nnet::multinom(formula, data = data, trace = FALSE),
        error = function(e) NULL,
        warning = function(w) NULL
      )
      
      # Si el modelo se ajustó correctamente, almacenar los resultados
      if (!is.null(model)) {
        # Extraer el BIC del modelo
        bic <- BIC(model)
        
        # Almacenar la información en la lista de resultados
        results[[length(results) + 1]] <- list(
          predictors = paste(terms, collapse = " + "),
          model = model,
          BIC = bic
        )
      }
    }
  }
  
  # Convertir la lista de resultados en un dataframe
  results_df <- results |>
    purrr::map_df(function(res) {
      data.frame(
        predictors = res$predictors,
        BIC = res$BIC,
        stringsAsFactors = FALSE
      )
    })
  
  # Ordenar los modelos por BIC de menor a mayor
  results_df <- results_df |> arrange(BIC)
  
  return(results_df)
}

best_subset_multinom_interactions_parallel <- function(y, x.vars, data) {
  # y       Nombre de la variable dependiente (cadena de texto)
  # x.vars  Vector de nombres de predictores (caracter)
  # data    Dataframe con los datos de entrenamiento
  
  # Cargar las librerías necesarias dentro de la función
  require(dplyr)
  require(purrr)
  require(tidyr)
  require(nnet)
  require(MASS)
  require(foreach)
  require(doParallel)
  require(progressr)
  
  # Iniciar los gestores de progreso
  handlers(global = TRUE)
  handlers("txt")
  
  # Generar todas las combinaciones posibles de predictores (efectos principales)
  main_effects_list <- lapply(1:length(x.vars), function(i) {
    combn(x.vars, i, simplify = FALSE)
  }) |> unlist(recursive = FALSE)
  
  # Inicializar una lista para almacenar las fórmulas de los modelos
  formulas_list <- list()
  
  # Generar todas las fórmulas posibles con interacciones hasta de 3 variables
  for (main_effects in main_effects_list) {
    
    # Generar términos de interacción de hasta 3 variables
    interaction_terms <- character(0)  # Aseguramos que es un vector de caracteres
    
    # Para interacciones de 2 variables
    if (length(main_effects) >= 2) {
      interaction_terms_2way <- combn(main_effects, 2, function(x) paste(x, collapse = ":"), simplify = TRUE)
      interaction_terms <- c(interaction_terms, interaction_terms_2way)
    }
    
    # Para interacciones de 3 variables
    if (length(main_effects) >= 3) {
      interaction_terms_3way <- combn(main_effects, 3, function(x) paste(x, collapse = ":"), simplify = TRUE)
      interaction_terms <- c(interaction_terms, interaction_terms_3way)
    }
    
    # Generar todas las combinaciones posibles de efectos principales
    main_effects_subsets <- lapply(1:length(main_effects), function(i) {
      combn(main_effects, i, simplify = FALSE)
    }) |> unlist(recursive = FALSE)
    
    # Para cada subconjunto de efectos principales
    for (me in main_effects_subsets) {
      # Iniciar con los efectos principales
      terms <- me
      
      # Identificar interacciones cuyos efectos principales están en 'me'
      if (length(interaction_terms) > 0) {
        possible_interactions <- interaction_terms[
          vapply(interaction_terms, function(x) {
            vars_in_interaction <- unlist(strsplit(x, ":"))
            all(vars_in_interaction %in% me)
          }, FUN.VALUE = logical(1))
        ]
      } else {
        possible_interactions <- character(0)
      }
      
      # Generar todas las combinaciones posibles de estas interacciones
      interaction_subsets <- list(character(0))  # Incluir el caso sin interacciones
      if (length(possible_interactions) > 0) {
        interaction_combinations <- lapply(1:length(possible_interactions), function(i) {
          combn(possible_interactions, i, simplify = FALSE)
        }) |> unlist(recursive = FALSE)
        interaction_subsets <- c(interaction_subsets, interaction_combinations)
      }
      
      # Para cada combinación de interacciones
      for (ints in interaction_subsets) {
        full_terms <- c(terms, ints)
        
        # Crear la fórmula del modelo y almacenarla
        formula_str <- paste(y, "~", paste(full_terms, collapse = "+"))
        formulas_list <- append(formulas_list, list(formula_str))
      }
    }
  }
  
  # Eliminar posibles duplicados de fórmulas
  formulas_list <- unique(formulas_list)
  
  # Total de modelos a ajustar
  total_models <- length(formulas_list)
  
  # Iniciar el progreso
  p <- progressor(steps = total_models)
  
  # Ajustar los modelos en paralelo usando foreach
  results_list <- foreach(i = 1:total_models, .packages = c("nnet", "MASS"), .combine = 'rbind') %dopar% {
    formula_str <- formulas_list[[i]]
    formula <- as.formula(formula_str)
    
    # Ajustar el modelo
    model <- tryCatch(
      nnet::multinom(formula, data = data, trace = FALSE),
      error = function(e) NULL,
      warning = function(w) NULL
    )
    
    # Actualizar el progreso
    p(sprintf("Ajustando modelo %d de %d", i, total_models))
    
    # Si el modelo se ajustó correctamente, almacenar los resultados
    if (!is.null(model)) {
      bic <- BIC(model)
      data.frame(
        predictors = formula_str,
        BIC = bic,
        stringsAsFactors = FALSE
      )
    } else {
      NULL
    }
  }
  
  # Convertir los resultados a dataframe y ordenar por BIC
  results_df <- as.data.frame(results_list)
  results_df <- results_df |> arrange(BIC)
  
  return(results_df)
}


num_cores <- parallel::detectCores() - 1
cl <- makeCluster(num_cores)
registerDoParallel(cl)

#pacman job kableExtra tidyverse cluster WeightedCluster devtools TraMineR TraMineRextras NbClust haven ggseqplot gridExtra Tmisc factoextra reticulate withr rmarkdown quarto

options(knitr.kable.NA = '')


#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#
#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#

knitr::knit_hooks$set(time_it = local({
  now <- NULL
  function(before, options) {
    if (before) {
      # record the current time before each chunk
      now <<- Sys.time()
    } else {
      # calculate the time difference after a chunk
      res <- ifelse(difftime(Sys.time(), now)>(60^2),difftime(Sys.time(), now)/(60^2),difftime(Sys.time(), now)/(60^1))
      # return a character string to show the time
      x<-ifelse(difftime(Sys.time(), now)>(60^2),paste("Tiempo que demora esta sección:", round(res,1), "horas"),paste("Tiempo que demora esta sección:", round(res,1), "minutos"))
      paste('<div class="message">', gsub('##', '\n', x),'</div>', sep = '\n')
    }
  }
}))
knitr::opts_chunk$set(time_it = TRUE)

#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:
#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:

format_cells <- function(df, rows ,cols, value = c("italics", "bold", "strikethrough")){
  
  # select the correct markup
  # one * for italics, two ** for bold
  map <- setNames(c("*", "**", "~~"), c("italics", "bold", "strikethrough"))
  markup <- map[value]  
  
  for (r in rows){
    for(c in cols){
      
      # Make sure values are not factors
      df[[c]] <- as.character( df[[c]])
      
      # Update formatting
      df[r, c] <- ifelse(nchar(df[r, c])==0,"",paste0(markup, gsub(" ", "", df[r, c]), markup))
    }
  }
  
  return(df)
}
#To produce line breaks in messages and warnings
knitr::knit_hooks$set(
   error = function(x, options) {
     paste('\n\n<div class="alert alert-danger" style="font-size: small !important;">',
           gsub('##', '\n', gsub('^##\ Error', '**Error**', x)),
           '</div>', sep = '\n')
   },
   warning = function(x, options) {
     paste('\n\n<div class="alert alert-warning" style="font-size: small !important;">',
           gsub('##', '\n', gsub('^##\ Warning:', '**Warning**', x)),
           '</div>', sep = '\n')
   },
   message = function(x, options) {
     paste('<div class="message" style="font-size: small !important;">',
           gsub('##', '\n', x),
           '</div>', sep = '\n')
   }
)

#_#_#_#_#_#_#_#_#_#_#_#_#_
invisible("Function to format CreateTableOne into a database")

as.data.frame.TableOne <- function(x, ...) {capture.output(print(x,showAllLevels = TRUE, varLabels = T,...) -> x)
  y <- as.data.frame(x)
  y$characteristic <- dplyr::na_if(rownames(x), "")
  y <- y |>
    fill(characteristic, .direction = "down") |>
    dplyr::select(characteristic, everything())
  rownames(y) <- NULL
  y}
#_#_#_#_#_#_#_#_#_#_#_#_#_
# Austin, P. C. (2009). The Relative Ability of Different Propensity 
# Score Methods to Balance Measured Covariates Between 
# Treated and Untreated Subjects in Observational Studies. Medical 
# Decision Making. https://doi.org/10.1177/0272989X09341755
smd_bin <- function(x,y){
  z <- x*(1-x)
  t <- y*(1-y)
  k <- sum(z,t)
  l <- k/2
  
  return((x-y)/sqrt(l))
  
}
#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:
#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:

format_table_vec <- function(tbl, digits = 1) {
  counts <- as.numeric(tbl)
  percentages <- prop.table(tbl) * 100
  
  formatted <- sapply(seq_along(counts), function(i) {
    p_val <- percentages[i]
    # Si el porcentaje es prácticamente entero, formatea sin decimales
    if (abs(p_val - round(p_val)) < .Machine$double.eps^0.5) {
      p_str <- sprintf("%.0f", p_val)
    } else {
      p_str <- sprintf(paste0("%.", digits, "f"), p_val)
    }
    paste0(counts[i], " (", p_str, ")")
  })
  
  formatted
}
#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:
#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:


if(.Platform$OS.type == "windows") withAutoprint({
  memory.size()
  memory.size(TRUE)
  memory.limit()
})
> memory.size()
[1] Inf
> memory.size(TRUE)
[1] Inf
> memory.limit()
[1] Inf
Código
#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:
#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:
func_tab_range_clus<-
function(range_clus){
rbind.data.frame(
  lapply(
    list(
      as.vector(rev(sort(table(range_clus$clustering$cluster2)))),
      as.vector(rev(sort(table(range_clus$clustering$cluster3)))),
      as.vector(rev(sort(table(range_clus$clustering$cluster4)))),
      as.vector(rev(sort(table(range_clus$clustering$cluster5)))),
      as.vector(rev(sort(table(range_clus$clustering$cluster6)))),
      as.vector(rev(sort(table(range_clus$clustering$cluster7)))),
      as.vector(rev(sort(table(range_clus$clustering$cluster8)))),
      as.vector(rev(sort(table(range_clus$clustering$cluster9)))),
      as.vector(rev(sort(table(range_clus$clustering$cluster10)))),
      as.vector(rev(sort(table(range_clus$clustering$cluster11)))),
      as.vector(rev(sort(table(range_clus$clustering$cluster12)))),
      as.vector(rev(sort(table(range_clus$clustering$cluster13)))),
      as.vector(rev(sort(table(range_clus$clustering$cluster14)))),
      as.vector(rev(sort(table(range_clus$clustering$cluster15))))
    ),
    function(x) {
      length_out <- max(sapply(list(
        as.vector(rev(sort(table(range_clus$clustering$cluster2)))),
        as.vector(rev(sort(table(range_clus$clustering$cluster3)))),
        as.vector(rev(sort(table(range_clus$clustering$cluster4)))),
        as.vector(rev(sort(table(range_clus$clustering$cluster5)))),
        as.vector(rev(sort(table(range_clus$clustering$cluster6)))),
        as.vector(rev(sort(table(range_clus$clustering$cluster7)))),
        as.vector(rev(sort(table(range_clus$clustering$cluster8)))),
        as.vector(rev(sort(table(range_clus$clustering$cluster9)))),
        as.vector(rev(sort(table(range_clus$clustering$cluster10)))),
        as.vector(rev(sort(table(range_clus$clustering$cluster11)))),
        as.vector(rev(sort(table(range_clus$clustering$cluster12)))),
        as.vector(rev(sort(table(range_clus$clustering$cluster13)))),
        as.vector(rev(sort(table(range_clus$clustering$cluster14)))),
        as.vector(rev(sort(table(range_clus$clustering$cluster15))))
      ), length))
      c(x, rep(NA, length_out - length(x)))
    }
  )
)|>
  t() |> 
  data.frame()|>
  `rownames<-`(NULL)
}


frobenius_norm <- function(matrix1, matrix2) {
    if (!all(dim(matrix1) == dim(matrix2))) {
        stop("Matrices must have the same dimensions")
    }
    
    # Replace NA values with 0 (or any other desired default)
    matrix1[is.na(matrix1)] <- 0
    matrix2[is.na(matrix2)] <- 0
    
    # Calculate the residuals
    residuals <- matrix1 - matrix2
    
    # Frobenius norm
    frobenius <- sqrt(sum(residuals^2))
    return(frobenius)
}



#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:
#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:
confcqi2 <- function(nullstat, quant, n){
  alpha <- (1-quant)/2
  #calpha <- alpha+(alpha-1)/n
  #print(c(calpha, alpha))
  #minmax <- quantile(nullstat, c(calpha, 1-calpha))
  minmax <- quantile(nullstat, c(alpha, 1-alpha))
  return(minmax)
}

normstatcqi2 <- function(bcq, stat, norm=TRUE){
  origstat <- bcq$clustrange$stats[, stat]
  nullstat <- bcq$stats[[stat]]
  #normstat <- rbind(nullstat, origstat)
  if(norm){
    for(i in seq_along(origstat)){
      mx <- mean(nullstat[, i])
      sdx <- sd(nullstat[, i])
      nullstat[ , i] <- (nullstat[, i]-mx)/sdx
      origstat[i] <- (origstat[i]-mx)/sdx
    }
  }
  alldatamax <- apply(nullstat, 1, max)#as.vector(xx)
  sumcqi <- list(origstat=origstat, nullstat=nullstat, alldatamax=alldatamax)
  return(sumcqi)
}
print.seqnullcqi.powder <- function(x, norm = FALSE, quant = 0.95, digits = 2, 
                                    append = FALSE, ...) {
    cat("Parametric bootstrap cluster analysis validation\n")
    cat("Sequence analysis null model:", deparse(x$nullmodel), "\n")
    cat("Number of bootstraps:", x$R, "\n")
    cat("Clustering method:", ifelse(x$kmedoid, "PAM/K-Medoid", paste0("hclust with ", x$hclust.method)), "\n")
    cat("Seqdist arguments:", deparse(x$seqdist.args), "\n\n\n")
    alls <- as.data.frame(x$clustrange$stats)
    quants <- rep("", ncol(alls))
    names(quants) <- colnames(alls)
    for (ss in colnames(alls)) {
        sumcqi <- normstatcqi2(x, stat = ss, norm = norm)
        alls[, ss] <- as.character(round(sumcqi$origstat, digits = digits))
        borne <- as.character(round(confcqi2(sumcqi$alldatamax, quant, x$R), digits = digits))
        quants[ss] <- paste0("[", borne[1], "; ", borne[2], "]")
    }
    results_tibble <- tibble::as_tibble(rbind(alls, rep("", length(quants)), quants))
    # Print a summary to the console for immediate feedback
    rownames(results_tibble) <- c(rownames(x$clustrange$stats), "", paste("Null Max-T", quant, "interval"))
    
    results_df <- as.data.frame(results_tibble)
    print(results_tibble, ...)
    return(list(
      results_tibble= results_tibble, 
      results_df= results_df
      ))
}

#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:
##:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:
# Función para aplicar la prueba de Fisher a todas las combinaciones de filas usando todas las columnas
fisher_posthoc_all_cols <- function(contingency_table) {
  # Obtener combinaciones de filas (pares)
  row_pairs <- combn(rownames(contingency_table), 2, simplify = FALSE)
  
  # Aplicar la prueba de Fisher a cada par de filas usando todas las columnas al mismo tiempo
  results <- map_dfr(row_pairs, function(pair) {
    # Crear tabla de 2xN para el par de filas en todas las columnas
    sub_table <- contingency_table[pair, , drop = FALSE]
    
    # Aplicar el test de Fisher
    test_result <- fisher.test(sub_table, 
                                 simulate.p.value=T,
                                 B=1e4)
    
    # Devolver los resultados en un data frame
    tibble(
      Row1 = pair[1],
      Row2 = pair[2],
      p.value = test_result$p.value
    )
  })
  
  # Ajustar p-valores usando el método de Holm
  results <- results |>
    mutate(p.adjusted = p.adjust(p.value, method = "holm"))
  
  return(results)
}
#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:
#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:
save_base_plot_as_grob <- function(plot_expr, res=300,  width = 1600, height= 1200) {
    # Crea un archivo temporal con extensión .png
    filename <- tempfile(fileext = ".png")
    
    # Guarda el gráfico en alta resolución en el archivo temporal
    png(filename, width = width, height = height, res = res)
    replayPlot(plot_expr)  # Reproduce el gráfico grabado
    dev.off()  # Cierra el dispositivo gráfico
    
    # Convierte el archivo PNG en un objeto gráfico (grob)
    grob <- grid::rasterGrob(png::readPNG(filename), interpolate = TRUE)
    
    return(grob)  # Devuelve el grob
}
#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:
#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:
chisq_cramerv<- function(contingency_table){
  chisq_test <- chisq.test(contingency_table)
  cramers_v <- sqrt(chisq_test$statistic / (sum(contingency_table) * (min(dim(contingency_table)) - 1)))
  
  list(chisq_statistic= sprintf("%1.2f", chisq_test$statistic), chisq_df= chisq_test$parameter, chisq_p_value = ifelse(chisq_test$p.value<.001, "<0.001", sprintf("%1.4f", chisq_test$p.value)), cramers_v = sprintf("%1.2f", cramers_v))
}

#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:
#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:
#
oneway_anova_effect_size <- function(values, group) {
  # Perform one-way ANOVA
  anova_result <- aov(values ~ group)
  
  # Summarize ANOVA results
  anova_summary <- summary(anova_result)
  
  # Extract sums of squares
  ss_between <- anova_summary[[1]]$"Sum Sq"[1]
  ss_total <- sum(anova_summary[[1]]$"Sum Sq")
  
  # Calculate eta-squared
  eta_squared <- ss_between / ss_total
  
  # Return ANOVA summary and effect size
  list(
    anova_summary = anova_summary,
    eta_squared = eta_squared
  )
}

#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:
#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:


#duración en cada estado
seq_mean_t<- function(bd=NULL, group= group){
  resultados<- by(bd, group, seqmeant)
  
  do.call(rbind, lapply(names(resultados), function(name) {
    data.frame(factor_inclusivo = name, resultados[[name]])
  }))
}


seqtrate_t<- function(bd=NULL, group= group){
    # Utilizar la función 'by' para calcular las tasas agrupadas por 'glosa_sexo'
    resultados <- by(bd, 
                     group, 
                     seqtrate)
    
    # Convertir los resultados en un data frame en formato largo
    resultados_long <- do.call(rbind, lapply(names(resultados), function(sexo) {
      df <- as.data.frame(resultados[[sexo]])
      df$from <- rownames(df)
      df$glosa_sexo <- sexo
      df
    }))
    
    # Usar tidyr para convertir a formato largo
    library(tidyr)
    resultados_long <- pivot_longer(resultados_long, 
                                    cols = -c(from, glosa_sexo), 
                                    names_to = "to", 
                                    values_to = "rate")
    
    # Mostrar el data frame final
    print(resultados_long)
}


seqcount_t<- function(bd=NULL, group= group){
    # Utilizar la función 'by' para calcular las tasas agrupadas por 'glosa_sexo'
  resultados <- by(bd, 
                   group, 
                   function(x) seqtrate(x, count = TRUE))
    
    # Convertir los resultados en un data frame en formato largo
    resultados_long <- do.call(rbind, lapply(names(resultados), function(sexo) {
      df <- as.data.frame(resultados[[sexo]])
      df$from <- rownames(df)
      df$glosa_sexo <- sexo
      df
    }))
    
    # Usar tidyr para convertir a formato largo
    library(tidyr)
    resultados_long <- pivot_longer(resultados_long, 
                                    cols = -c(from, glosa_sexo), 
                                    names_to = "to", 
                                    values_to = "count")
    
    # Mostrar el data frame final
    print(resultados_long)
}
#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:
#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:

Descartamos objetos que no serán de interés para el análisis

Código
# Define el vector con los nombres de los objetos que quieres conservar
mis_objetos <- c(
  "as.data.frame.TableOne", "avs_por_cluster_month", "avs_por_cluster_quarter",
  "best_subset_multinom", "best_subset_multinom_interactions", "best_subset_multinom_interactions_parallel", "categories_hac_om2_m", "categories_pam_om4_q", "chisq_cramerv", "cl", "costmatrix_month", "costmatrix_quarter", "data_long_establecimiento_2024_std", "df_filled2", "dist_month_lcs", "dist_month_om", "dist_quarter_lcs", "dist_quarter_om", "dt_ing_calendar_month_t_desde_primera_adm_dedup", "dt_ing_calendar_quarter_t_desde_primera_adm_dedup", "fisher_posthoc_all_cols", "folder_path", "format_cells", "format_table_vec", "ing_dt_ing_calendar_month_t_desde_primera_adm_dedup_wide2_cens", "ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens", "lcs_dist_month", "lcs_dist_month_c", "lcs_dist_quarter", "lcs_dist_quarter_c", "max_clusters", "multinom_pivot_wider", "new_labels", "new_labels2", "num_cores", "om_dist_month", "om_dist_month_c", "om_dist_quarter", "om_dist_quarter_c", "oneway_anova_effect_size", "pamRange_month_lcs", "pamRange_month_lcs2", "pamRange_month_om", "pamRange_month_om2", "pamRange_quarter_lcs", "pamRange_quarter_lcs2", "pamRange_quarter_om", "pamRange_quarter_om2", "ratio_plot", "resultados_list", "seq_plot_hc_om2_m", "seq_plot_hc_om3_m", "seq_plot_pam_om2_m", "seq_plot_pam_om2_q", "seq_plot_pam_om3_q", "seq_plot_pam_om4_q", "seq_plot_pam_om6_q", "sil_hc_om_clus2_m", "sil_hc_om_clus2_q", "sil_hc_om_clus3_m", "sil_pam_om_clus2_m", "sil_pam_om_clus2_q", "sil_pam_om_clus3_q", "sil_pam_om_clus4_q", "sil_pam_om_clus6_q", "smd_bin", "States_Wide.seq_month_t_prim_adm", "States_Wide.seq_month_t_prim_adm_cens", "States_Wide.seq_month_t_prim_adm_RM_cens", "States_Wide.seq_quarter_t_prim_adm", "States_Wide.seq_quarter_t_prim_adm_cens", "States_Wide.seq_quarter_t_prim_adm_RM_cens", "seqcount_t", "seq_mean_t", "seqtrate_t")

# Filtrar el entorno global y eliminar todo lo que NO esté en ese vector
rm(list = setdiff(ls(), mis_objetos)); gc()
            used   (Mb) gc trigger    (Mb)   max used    (Mb)
Ncells   4502453  240.5   16485647   880.5   20607058  1100.6
Vcells 358285933 2733.6 2137006712 16304.1 2570222340 19609.3

Tiempo que demora esta sección: 0 minutos


Resultados

1. Trimestral

1.1. PAM (OM), sol 4 cluster- diagnósticos

Código
invisible("Me da buena: 0,61 en promedio. El problema está con 5710 y 6036 que son pésimos")
sil_pam_om_clus4_q_nostd<-
  silhouette(as.integer(pamRange_quarter_om$clustering$cluster4), as.dist(dist_quarter_om))

# Crear etiquetas personalizadas
cluster_labels <- paste0("Cluster ", 
          seq_along(attr(summary(sil_pam_om_clus4_q_nostd)$clus.avg.widths, "dimnames")[[1]]), 
          ":\nAWS ", sprintf("%1.2f",summary(sil_pam_om_clus4_q_nostd)$clus.avg.widths))

# Graficar con etiquetas personalizadas
fviz_silhouette(
  sil_pam_om_clus4_q_nostd, 
  lab.clusters = cluster_labels, # Etiquetas personalizadas para los clústeres
  print.summary=F) +
  scale_fill_grey(start = 0.2, end = 0.8, labels = cluster_labels) +  # Escala de grises
  scale_color_grey(start = 0.2, end = 0.8, labels = cluster_labels)+   # Escala de grises para los bordea
  ggtitle(NULL)+
  labs(y="Ancho medio de la silueta", x="Conglomerados")# Elimina el título

Código
ggsave("_figs/sil_plot_pam_om4_q_25.png", width = 8, height = 5, dpi = 500)

Tiempo que demora esta sección: 0.1 minutos

Vemos los diagnósticos que vienen después de aquellos cluster con más de un ingreso.

Código
cat("resumen de episodios")
df_filled2 |> 
    dplyr::filter(run %in% subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, clus_pam_om4=="6522, Un semestre TSM(1)")$run) |> 
    dplyr::select(run, diag1, diag2, diag3, diag4, diag5, diag6, diag7, diag8, diag9, diag10, diag11, fecha_egreso_rec_fmt, estab_homo) |> 
    dplyr::group_by(run) |>
    #dplyr::filter(row_number() != 1) |> 
    summarise(n=n()) |> pull(n) |> summary()

cat("Número de ususarios que tienen más de un episodio en este grupo")
df_filled2 |> 
    dplyr::filter(run %in% subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, clus_pam_om4=="6522, Un semestre TSM(1)")$run) |> 
    dplyr::select(run, diag1, diag2, diag3, diag4, diag5, diag6, diag7, diag8, diag9, diag10, diag11, fecha_egreso_rec_fmt, estab_homo) |> 
    dplyr::group_by(run) |>
    dplyr::filter(row_number() != 1) |> 
    summarise(n=n()) |> pull(n) |> length()

cat("de quienes pertenecen al grupo de un semestre")
length(subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, clus_pam_om4=="6522, Un semestre TSM(1)")$run)

diag_pam_om4_6522<-
df_filled2 |> 
  dplyr::filter(run %in% subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, clus_pam_om4=="6522, Un semestre TSM(1)")$run) |> 
  dplyr::select(run, diag1, diag2, diag3, diag4, diag5, diag6, diag7, diag8, diag9, diag10, diag11, fecha_egreso_rec_fmt, estab_homo) |> 
  dplyr::group_by(run) |>
  dplyr::filter(row_number() != 1) |>  # Elimina la primera observación de cada run
  dplyr::mutate(
    all_diags = paste(na.omit(c(diag1, diag2, diag3, diag4, diag5, diag6, diag7, diag8, diag9, diag10, diag11)), collapse = ", ")
  ) |>
  dplyr::summarise(
    all_diags = first(all_diags),
    fecha_egreso_rec_fmt = first(fecha_egreso_rec_fmt),
    estab_homo = first(estab_homo)
  ) |>
  dplyr::ungroup() |> 
  dplyr::pull(all_diags) |>  # Extraer la columna all_diags como vector
  strsplit(split = ", ") |>  # Separar cada diagnóstico por comas
  unlist()  # Convertir la lista en un vector
invisible("head(arrange(data.frame(table(diag_pam_om4_6522)),-Freq),20)")
invisible("Para chatgpt= estos son códigos de CIE-10, descríbeme brevemente cada uno en markdown en formato 'Cód. CIE-10 (n=Freq) - [descripción] '")

cat("número de diagnósticos distintos")
length(diag_pam_om4_6522)

 ggplot( head(arrange(data.frame(table(diag_pam_om4_6522)),-Freq),20), aes(x = reorder(diag_pam_om4_6522, -Freq), y = Freq)) +
    geom_bar(stat = "identity", fill = "steelblue") +
    labs(title = "Los 20 diagnósticos más frecuentes",
         x = "Diagnósticos",
         y = "Frecuencias") +
    theme(axis.text.x = element_text(angle = 45, hjust = 1, size = 12),
          axis.title.x = element_text(size = 12),
          axis.text.y = element_text(size = 12),
          axis.title.y = element_text(size = 12))

Código
#
# F329 (n=134) - Episodio depresivo no especificado  
# F322 (n=103) - Episodio depresivo grave sin síntomas psicóticos  
# F609 (n=96) - Otros trastornos específicos de la personalidad  
# F603 (n=95) - Trastorno de la personalidad emocionalmente inestable, tipo límite  
# F209 (n=66) - Esquizofrenia no especificada  
# F192 (n=53) - Trastornos mentales y del comportamiento debidos al uso de múltiples drogas y al uso de otras sustancias psicoactivas  
# F319 (n=49) - Trastorno depresivo recurrente, episodio actual no especificado  
# F200 (n=45) - Esquizofrenia paranoide  
# F432 (n=38) - Trastornos de adaptación 
# F323 (n=35) - Episodio depresivo grave con síntomas psicóticos  
# Z915 (n=32) - Antecedentes personales de traumatismo no clasificado en otra parte  
# C490 (n=29) - Neoplasia maligna del tejido conectivo y de los tejidos blandos, de localización no especificada  
# G909 (n=29) - Trastorno del sistema nervioso no especificado  
# F431 (n=28) - Reacción al estrés agudo y trastornos de adaptación  
# E669 (n=26) - Obesidad, no especificada
# Z511 (n=24) - Atención sanitaria para radioterapia  
# F29X (n=21) - Psicosis no orgánica no especificada  
# F419 (n=20) - Trastorno de ansiedad no especificado  
# C901 (n=16) - Leucemia de células plasmáticas
# F199 (n=16) - Trastornos mentales y de compurtamiento por el uso de múltiples drogas y uso de otras sustancias piscoactivas
resumen de episodios   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  1.000   2.000   3.000   4.108   5.000  36.000 
Número de ususarios que tienen más de un episodio en este grupo[1] 372
de quienes pertenecen al grupo de un semestre[1] 399
número de diagnósticos distintos[1] 2192

Tiempo que demora esta sección: 0 minutos

Entre quienes se encuentren en un semestre en el sistema por TSM y presentan un segundo episodio, de las 20 condiciones más frecuentes, al menos el 50% se caracteriza por episodios depresivos no especificado (F329), trastornos de la personalidad tipo límite (F603), otros trastornos específicos de la personalidad (F609) y episodios depresivos graves sin síntomas psicóticos (F322) y esquizofrenia no especificada (F209).

Código
# Trastornos mentales orgánicos: F00.0-F09.9 (F000 a F099)
in_organic <- Vectorize(function(codigo) {
  if (is.na(codigo)) return(FALSE)
  grepl("^F0[0-9]", codigo)
})

# Trastornos por uso de sustancias: F10.0-F19.9 (F10 a F19)
in_substance <- Vectorize(function(codigo) {
  if (is.na(codigo)) return(FALSE)
  grepl("^F1[0-9]", codigo)
})

# Esquizofrenia: F20.0-F20.9 (F20)
in_esquizofrenia <- Vectorize(function(codigo) {
  if (is.na(codigo)) return(FALSE)
  grepl("^F20", codigo)
})

# Otros trastornos psicóticos no afectivos: F21.0-F29.9 (F21 a F29)
in_otros_psicoticos <- Vectorize(function(codigo) {
  if (is.na(codigo)) return(FALSE)
  grepl("^F2[1-9]", codigo)
})

# Trastornos bipolares: F30.0-F31.9 (F30 o F31)
in_bipolares <- Vectorize(function(codigo) {
  if (is.na(codigo)) return(FALSE)
  grepl("^(F30|F31)", codigo)
})

# Trastornos depresivos y otros del estado de ánimo: F32.0-F39.9 (F32 a F39)
in_depresivos <- Vectorize(function(codigo) {
  if (is.na(codigo)) return(FALSE)
  grepl("^F3[2-9]", codigo)
})

# Trastornos de ansiedad: F40.0-F49.9 (F40 a F49)
in_ansiedad <- Vectorize(function(codigo) {
  if (is.na(codigo)) return(FALSE)
  grepl("^F4[0-9]", codigo)
})

# Trastornos de la personalidad: F60.0-F69.9 (F60 a F69)
in_personalidad <- Vectorize(function(codigo) {
  if (is.na(codigo)) return(FALSE)
  grepl("^F6[0-9]", codigo)
})

# LESIONES AUTOINFLIGIDAS INTENCIONALMENTE (X60-X84)
in_lesiones <- Vectorize(function(codigo) {
  if (is.na(codigo)) return(FALSE)
  grepl("^X6[0-9]|^X7[0-9]|^X8[0-4]", codigo)
})

#Mortier, P., Conde, S., Alayo, I., Amigo, F., Ballester, L., Amell, R. C., Guinart, D., Contaldo, S. F., Ferrer, M., Leis, A., Mayer, M. A., Portillo-Van Diest, A., Puértolas-Gracia, B., Ramírez-Anguita, J. M., Peña-Salazar, C., Sanz, F., Kessler, R. C., Palao, D., Sola, V. P., . . .  Alonso, J. (2024). Premature Death, Suicide, and Nonlethal Intentional Self-Harm After Psychiatric Discharge. JAMA Network Open, 7(6), e2417131. https://doi.org/10.1001/jamanetworkopen.2024.17131
in_lesiones_amplio <- Vectorize(function(codigo) {
  if (is.na(codigo)) return(FALSE)
  grepl("^(T3[6-9]|T4[0-9]|T5[0-9]|T6[0-5])", codigo)
})

agregar_columnas_icd <- function(df) {
  # Especificamos las columnas de diagnóstico
  diag_cols <- paste0("diag", 1:11)
  
  df |>
    mutate(
      organic = rowSums(across(all_of(diag_cols), ~ in_organic(.))) > 0,
      substance = rowSums(across(all_of(diag_cols), ~ in_substance(.))) > 0,
      esquizofrenia = rowSums(across(all_of(diag_cols), ~ in_esquizofrenia(.))) > 0,
      otros_psicoticos = rowSums(across(all_of(diag_cols), ~ in_otros_psicoticos(.))) > 0,
      bipolares = rowSums(across(all_of(diag_cols), ~ in_bipolares(.))) > 0,
      depresivos = rowSums(across(all_of(diag_cols), ~ in_depresivos(.))) > 0,
      ansiedad = rowSums(across(all_of(diag_cols), ~ in_ansiedad(.))) > 0,
      personalidad = rowSums(across(all_of(diag_cols), ~ in_personalidad(.))) > 0
    )
}

#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_
#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_
#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_

cat("2025-03-01: general")
first_episode<-
df_filled2 |> 
    dplyr::filter(run %in% ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$run)|> 
    dplyr::select(run, diag1, diag2, diag3, diag4, diag5, diag6, diag7, diag8, diag9, diag10, diag11, fecha_egreso_rec_fmt, estab_homo) |> 
    dplyr::group_by(run) |>
    dplyr::filter(row_number() == 1)|>
    dplyr::ungroup()

second_episode<-
df_filled2 |> 
    dplyr::filter(run %in% ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$run)|> 
    dplyr::select(run, diag1, diag2, diag3, diag4, diag5, diag6, diag7, diag8, diag9, diag10, diag11, fecha_egreso_rec_fmt, estab_homo) |> 
    dplyr::group_by(run) |>
    dplyr::filter(row_number() == 2)|>
    dplyr::ungroup()

cat(paste0("Second episodes, total: ", nrow(second_episode)))

first_episode_rec<-
agregar_columnas_icd(first_episode)
  
tot_cie10_clas<-
rbind.data.frame(
  format_table_vec(table(factor(first_episode_rec$organic, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_rec$substance, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_rec$esquizofrenia, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_rec$otros_psicoticos, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_rec$bipolares, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_rec$depresivos, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_rec$ansiedad, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_rec$personalidad, levels = c(FALSE, TRUE))))                 )|>
    (\(df) {
  colnames(df) <- c("FALSE", "TRUE"); rownames(df)<-NULL; df
      })()
#         FALSE        TRUE
# 1 4858 (80.5) 1180 (19.5)
# 2 5612 (92.9)   426 (7.1)
# 3 5645 (93.5)   393 (6.5)
# 4 5652 (93.6)   386 (6.4)
# 5 4215 (69.8) 1823 (30.2)
# 6 5072 (84.0)  966 (16.0)
# 7 4903 (81.2) 1135 (18.8)
# 

second_episode_rec<-
agregar_columnas_icd(second_episode)
  
tot_cie10_clas_2nd<-
rbind.data.frame(
  format_table_vec(table(factor(second_episode_rec$organic, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_rec$substance, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_rec$esquizofrenia, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_rec$otros_psicoticos, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_rec$bipolares, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_rec$depresivos, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_rec$ansiedad, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_rec$personalidad, levels = c(FALSE, TRUE))))                 )|>
    (\(df) {
  colnames(df) <- c("FALSE", "TRUE"); rownames(df)<-NULL; df
      })()

cat("2025-03-01: TSM 1 semestre")
first_episode_1_trim_tsm<-
df_filled2 |> 
  dplyr::filter(run %in% subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, clus_pam_om4=="6623, Un trimestre, TSM(4)")$run) |> 
    dplyr::select(run, diag1, diag2, diag3, diag4, diag5, diag6, diag7, diag8, diag9, diag10, diag11, fecha_egreso_rec_fmt, estab_homo) |> 
    dplyr::group_by(run) |>
    dplyr::filter(row_number() == 1)|>
    dplyr::ungroup()
second_episode_1_trim_tsm<-
df_filled2 |> 
  dplyr::filter(run %in% subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, clus_pam_om4=="6623, Un trimestre, TSM(4)")$run) |> 
    dplyr::select(run, diag1, diag2, diag3, diag4, diag5, diag6, diag7, diag8, diag9, diag10, diag11, fecha_egreso_rec_fmt, estab_homo) |> 
    dplyr::group_by(run) |>
    dplyr::filter(row_number() == 2)|>
    dplyr::ungroup()

cat(paste0("Second episodes, First quarter, MH: ", nrow(second_episode_1_trim_tsm)))

cat("2025-03-01: TSM 2 trimestres")
first_episode_tsm_1_sem_tsm<-
df_filled2 |> 
  dplyr::filter(run %in% subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, clus_pam_om4=="6522, Un semestre TSM(1)")$run) |> 
    dplyr::select(run, diag1, diag2, diag3, diag4, diag5, diag6, diag7, diag8, diag9, diag10, diag11, fecha_egreso_rec_fmt, estab_homo) |> 
    dplyr::group_by(run) |>
    dplyr::filter(row_number() == 1)|>
    dplyr::ungroup()
second_episode_tsm_1_sem_tsm<-
df_filled2 |> 
  dplyr::filter(run %in% subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, clus_pam_om4=="6522, Un semestre TSM(1)")$run) |> 
    dplyr::select(run, diag1, diag2, diag3, diag4, diag5, diag6, diag7, diag8, diag9, diag10, diag11, fecha_egreso_rec_fmt, estab_homo) |> 
    dplyr::group_by(run) |>
    dplyr::filter(row_number() == 2)|>
    dplyr::ungroup()

cat(paste0("Second episodes, First semester, MH: ", nrow(second_episode_tsm_1_sem_tsm)))


cat("2025-03-01: Comorbilidad")
first_episode_com<-
df_filled2 |> 
  dplyr::filter(run %in% subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, clus_pam_om4=="6574, Comorbilidad un trimestre(2)")$run) |> 
    dplyr::select(run, diag1, diag2, diag3, diag4, diag5, diag6, diag7, diag8, diag9, diag10, diag11, fecha_egreso_rec_fmt, estab_homo) |> 
    dplyr::group_by(run) |>
    dplyr::filter(row_number() == 1)|>
    dplyr::ungroup()
second_episode_com<-
df_filled2 |> 
  dplyr::filter(run %in% subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, clus_pam_om4=="6574, Comorbilidad un trimestre(2)")$run) |> 
    dplyr::select(run, diag1, diag2, diag3, diag4, diag5, diag6, diag7, diag8, diag9, diag10, diag11, fecha_egreso_rec_fmt, estab_homo) |> 
    dplyr::group_by(run) |>
    dplyr::filter(row_number() == 2)|>
    dplyr::ungroup()

cat(paste0("Second episodes, First quarter, Comorbidity: ", nrow(second_episode_com)))


cat("2025-03-01: TUS")
first_episode_tus<-
df_filled2 |> 
  dplyr::filter(run %in% subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, clus_pam_om4=="6612, Un trimestre, TUS(3)")$run) |> 
    dplyr::select(run, diag1, diag2, diag3, diag4, diag5, diag6, diag7, diag8, diag9, diag10, diag11, fecha_egreso_rec_fmt, estab_homo) |> 
    dplyr::group_by(run) |>
    dplyr::filter(row_number() == 1)|>
    dplyr::ungroup()
second_episode_tus<-
df_filled2 |> 
  dplyr::filter(run %in% subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, clus_pam_om4=="6612, Un trimestre, TUS(3)")$run) |> 
    dplyr::select(run, diag1, diag2, diag3, diag4, diag5, diag6, diag7, diag8, diag9, diag10, diag11, fecha_egreso_rec_fmt, estab_homo) |> 
    dplyr::group_by(run) |>
    dplyr::filter(row_number() == 2)|>
    dplyr::ungroup()
cat(paste0("Second episodes, First quarter, SUD: ", nrow(second_episode_tus)))


first_episode_1_trim_tsm_rec<-
agregar_columnas_icd(first_episode_1_trim_tsm)

prim_trim_tsm_clas<-
rbind.data.frame(
  format_table_vec(table(factor(first_episode_1_trim_tsm_rec$organic, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_1_trim_tsm_rec$substance, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_1_trim_tsm_rec$esquizofrenia, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_1_trim_tsm_rec$otros_psicoticos, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_1_trim_tsm_rec$bipolares, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_1_trim_tsm_rec$depresivos, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_1_trim_tsm_rec$ansiedad, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_1_trim_tsm_rec$personalidad, levels = c(FALSE, TRUE))))
)|>
    (\(df) {
  colnames(df) <- c("FALSE", "TRUE"); rownames(df)<-NULL; df
      })()
#         FALSE        TRUE
# 1 4500 (94.0)   288 (6.0)
# 2 4427 (92.5)   361 (7.5)
# 3 4457 (93.1)   331 (6.9)
# 4 4440 (92.7)   348 (7.3)
# 5 3108 (64.9) 1680 (35.1)
# 6 3892 (81.3)  896 (18.7)
# 7 3785 (79.1) 1003 (20.9)

second_episode_1_trim_tsm_rec<-
agregar_columnas_icd(second_episode_1_trim_tsm)

second_trim_tsm_clas<-
rbind.data.frame(
  format_table_vec(table(factor(second_episode_1_trim_tsm_rec$organic, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_1_trim_tsm_rec$substance, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_1_trim_tsm_rec$esquizofrenia, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_1_trim_tsm_rec$otros_psicoticos, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_1_trim_tsm_rec$bipolares, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_1_trim_tsm_rec$depresivos, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_1_trim_tsm_rec$ansiedad, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_1_trim_tsm_rec$personalidad, levels = c(FALSE, TRUE))))
)|>
    (\(df) {
  colnames(df) <- c("FALSE", "TRUE"); rownames(df)<-NULL; df
      })()


first_episode_tsm_1_sem_tsm_rec<-
agregar_columnas_icd(first_episode_tsm_1_sem_tsm)

prim_sem_tsm_clas<-
rbind.data.frame(
  format_table_vec(table(factor(first_episode_tsm_1_sem_tsm_rec$organic, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_tsm_1_sem_tsm_rec$substance, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_tsm_1_sem_tsm_rec$esquizofrenia, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_tsm_1_sem_tsm_rec$otros_psicoticos, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_tsm_1_sem_tsm_rec$bipolares, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_tsm_1_sem_tsm_rec$depresivos, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_tsm_1_sem_tsm_rec$ansiedad, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_tsm_1_sem_tsm_rec$personalidad, levels = c(FALSE, TRUE))))
)|>
    (\(df) {
  colnames(df) <- c("FALSE", "TRUE"); rownames(df)<-NULL; df
      })()
#        FALSE       TRUE
# 1 320 (90.4)   34 (9.6)
# 2 308 (87.0)  46 (13.0)
# 3 329 (92.9)   25 (7.1)
# 4 331 (93.5)   23 (6.5)
# 5 241 (68.1) 113 (31.9)
# 6 299 (84.5)  55 (15.5)
# 7 288 (81.4)  66 (18.6)
# 
#
second_episode_tsm_1_sem_tsm_rec<-
agregar_columnas_icd(second_episode_tsm_1_sem_tsm)

second_sem_tsm_clas<-
rbind.data.frame(
  format_table_vec(table(factor(second_episode_tsm_1_sem_tsm_rec$organic, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_tsm_1_sem_tsm_rec$substance, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_tsm_1_sem_tsm_rec$esquizofrenia, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_tsm_1_sem_tsm_rec$otros_psicoticos, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_tsm_1_sem_tsm_rec$bipolares, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_tsm_1_sem_tsm_rec$depresivos, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_tsm_1_sem_tsm_rec$ansiedad, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_tsm_1_sem_tsm_rec$personalidad, levels = c(FALSE, TRUE))))
)|>
    (\(df) {
  colnames(df) <- c("FALSE", "TRUE"); rownames(df)<-NULL; df
      })()


first_episode_com_rec<-
    agregar_columnas_icd(first_episode_com)

prim_trim_com_clas<-
rbind.data.frame(
  format_table_vec(table(factor(first_episode_com_rec$organic, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_com_rec$substance, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_com_rec$esquizofrenia, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_com_rec$otros_psicoticos, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_com_rec$bipolares, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_com_rec$depresivos, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_com_rec$ansiedad, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_com_rec$personalidad, levels = c(FALSE, TRUE))))
)|>
    (\(df) {
  colnames(df) <- c("FALSE", "TRUE"); rownames(df)<-NULL; df
      })()
#        FALSE       TRUE
# 1   18 (8.5) 194 (91.5)
# 2 193 (91.0)   19 (9.0)
# 3 175 (82.5)  37 (17.5)
# 4 197 (92.9)   15 (7.1)
# 5 182 (85.8)  30 (14.2)
# 6 197 (92.9)   15 (7.1)
# 7 146 (68.9)  66 (31.1)


second_episode_com_rec<-
    agregar_columnas_icd(second_episode_com)

second_trim_com_clas<-
rbind.data.frame(
  format_table_vec(table(factor(second_episode_com_rec$organic, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_com_rec$substance, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_com_rec$esquizofrenia, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_com_rec$otros_psicoticos, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_com_rec$bipolares, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_com_rec$depresivos, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_com_rec$ansiedad, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_com_rec$personalidad, levels = c(FALSE, TRUE))))
)|>
    (\(df) {
  colnames(df) <- c("FALSE", "TRUE"); rownames(df)<-NULL; df
      })()



first_episode_tus_rec<-
    agregar_columnas_icd(first_episode_tus)

prim_trim_tus_clas<-
rbind.data.frame(
  format_table_vec(table(factor(first_episode_tus_rec$organic, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_tus_rec$substance, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_tus_rec$esquizofrenia, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_tus_rec$otros_psicoticos, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_tus_rec$bipolares, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_tus_rec$depresivos, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_tus_rec$ansiedad, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(first_episode_tus_rec$personalidad, levels = c(FALSE, TRUE))))
)|>
    (\(df) {
  colnames(df) <- c("FALSE", "TRUE"); rownames(df)<-NULL; df
      })()
#       FALSE       TRUE
# 1  20 (2.9) 664 (97.1)
# 2 684 (100)  684 (0.0)
# 3 684 (100)  684 (0.0)
# 4 684 (100)  684 (0.0)
# 5 684 (100)  684 (0.0)
# 6 684 (100)  684 (0.0)
# 7 684 (100)  684 (0.0)


second_episode_tus_rec<-
    agregar_columnas_icd(second_episode_tus)

second_trim_tus_clas<-
rbind.data.frame(
  format_table_vec(table(factor(second_episode_tus_rec$organic, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_tus_rec$substance, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_tus_rec$esquizofrenia, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_tus_rec$otros_psicoticos, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_tus_rec$bipolares, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_tus_rec$depresivos, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_tus_rec$ansiedad, levels = c(FALSE, TRUE)))),
  format_table_vec(table(factor(second_episode_tus_rec$personalidad, levels = c(FALSE, TRUE))))
)|>
    (\(df) {
  colnames(df) <- c("FALSE", "TRUE"); rownames(df)<-NULL; df
      })()

# chisq_test(
# cbind(
# table(factor(first_episode_rec$organic, levels = c(FALSE, TRUE))),
# table(factor(first_episode_rec$substance, levels = c(FALSE, TRUE))),
# table(factor(first_episode_rec$esquizofrenia, levels = c(FALSE, TRUE))),
# table(factor(first_episode_rec$otros_psicoticos, levels = c(FALSE, TRUE))),
# table(factor(first_episode_rec$bipolares, levels = c(FALSE, TRUE))),
# table(factor(first_episode_rec$depresivos, levels = c(FALSE, TRUE))),
# table(factor(first_episode_rec$ansiedad, levels = c(FALSE, TRUE))),
# table(factor(first_episode_rec$personalidad, levels = c(FALSE, TRUE)))
# ))
# #1 48304     3346.     0     7 Chi-square test ****    
# 
# fisher_test(cbind(
#     table(factor(first_episode_1_trim_tsm_rec$organic, levels = c(FALSE, TRUE))),
#     table(factor(first_episode_tsm_1_sem_tsm_rec$organic, levels = c(FALSE, TRUE))),
#     table(factor(first_episode_com_rec$organic, levels = c(FALSE, TRUE))),
#     table(factor(first_episode_tus_rec$organic, levels = c(FALSE, TRUE)))     
# ), simulate.p.value = T, B=1e5)
# #6722 0.00001 **** 
# fisher_test(cbind(
#     table(factor(first_episode_1_trim_tsm_rec$esquizofrenia, levels = c(FALSE, TRUE))),
#     table(factor(first_episode_tsm_1_sem_tsm_rec$esquizofrenia, levels = c(FALSE, TRUE))),
#     table(factor(first_episode_com_rec$esquizofrenia, levels = c(FALSE, TRUE))),
#     table(factor(first_episode_tus_rec$esquizofrenia, levels = c(FALSE, TRUE)))    
# ), simulate.p.value = T, B=1e5)
# #1  6722     1404. 3.37e-304     3 Chi-square test ****    
# chisq_test(cbind(
#     table(factor(first_episode_1_trim_tsm_rec$otros_psicoticos, levels = c(FALSE, TRUE))),
#     table(factor(first_episode_tsm_1_sem_tsm_rec$otros_psicoticos, levels = c(FALSE, TRUE))),
#     table(factor(first_episode_com_rec$otros_psicoticos, levels = c(FALSE, TRUE))),
#     table(factor(first_episode_tus_rec$otros_psicoticos, levels = c(FALSE, TRUE)))
# ))

# 6035. Un trimestre. TSM(4) (n=4.788)      6025. Un trimestre. TUS(3) (n=684)      5939. Un semestre TSM(1) (n=354)        5989. Comorbilidad un trimestre(2) (n=212)  


#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_
#
todes_suicidio<-
first_episode |>
    mutate( lesiones= rowSums(across(all_of(paste0("diag", 1:11)), ~ in_lesiones(.))) > 0 )
suicidio_1_trim_tsm<-
first_episode_1_trim_tsm |>
    mutate( lesiones= rowSums(across(all_of(paste0("diag", 1:11)), ~ in_lesiones(.))) > 0 )
suicidio_1_trim_tus<-
first_episode_tus |>
    mutate( lesiones= rowSums(across(all_of(paste0("diag", 1:11)), ~ in_lesiones(.))) > 0 )
suicidio_1_sem_tsm<-
first_episode_tsm_1_sem_tsm |>
    mutate( lesiones= rowSums(across(all_of(paste0("diag", 1:11)), ~ in_lesiones(.))) > 0 )
suicidio_com<-
first_episode_com |>
    mutate( lesiones= rowSums(across(all_of(paste0("diag", 1:11)), ~ in_lesiones(.))) > 0 )

todes_suicidio_amplio<-
first_episode |>
    mutate( lesiones= rowSums(across(all_of(paste0("diag", 1:11)), ~ in_lesiones_amplio(.))) > 0 )
suicidio_1_trim_tsm_amplio<-
first_episode_1_trim_tsm |>
    mutate( lesiones= rowSums(across(all_of(paste0("diag", 1:11)), ~ in_lesiones_amplio(.))) > 0 )
suicidio_1_trim_tus_amplio<-
first_episode_tus |>
    mutate( lesiones= rowSums(across(all_of(paste0("diag", 1:11)), ~ in_lesiones_amplio(.))) > 0 )
suicidio_1_sem_tsm_amplio<-
first_episode_tsm_1_sem_tsm |>
    mutate( lesiones= rowSums(across(all_of(paste0("diag", 1:11)), ~ in_lesiones_amplio(.))) > 0 )
suicidio_com_amplio<-
first_episode_com |>
    mutate( lesiones= rowSums(across(all_of(paste0("diag", 1:11)), ~ in_lesiones_amplio(.))) > 0 )

todes_suicidio_2nd<-
second_episode |>
    mutate( lesiones= rowSums(across(all_of(paste0("diag", 1:11)), ~ in_lesiones(.))) > 0 )
suicidio_1_trim_tsm_2nd<-
second_episode_1_trim_tsm |>
    mutate( lesiones= rowSums(across(all_of(paste0("diag", 1:11)), ~ in_lesiones(.))) > 0 )
suicidio_1_trim_tus_2nd<-
second_episode_tus |>
    mutate( lesiones= rowSums(across(all_of(paste0("diag", 1:11)), ~ in_lesiones(.))) > 0 )
suicidio_1_sem_tsm_2nd<-
second_episode_tsm_1_sem_tsm |>
    mutate( lesiones= rowSums(across(all_of(paste0("diag", 1:11)), ~ in_lesiones(.))) > 0 )
suicidio_com_2nd<-
second_episode_com |>
    mutate( lesiones= rowSums(across(all_of(paste0("diag", 1:11)), ~ in_lesiones(.))) > 0 )

todes_suicidio_amplio_2nd<-
second_episode |>
    mutate( lesiones= rowSums(across(all_of(paste0("diag", 1:11)), ~ in_lesiones_amplio(.))) > 0 )
suicidio_1_trim_tsm_amplio_2nd<-
second_episode_1_trim_tsm |>
    mutate( lesiones= rowSums(across(all_of(paste0("diag", 1:11)), ~ in_lesiones_amplio(.))) > 0 )
suicidio_1_trim_tus_amplio_2nd<-
second_episode_tus |>
    mutate( lesiones= rowSums(across(all_of(paste0("diag", 1:11)), ~ in_lesiones_amplio(.))) > 0 )
suicidio_1_sem_tsm_amplio_2nd<-
second_episode_tsm_1_sem_tsm |>
    mutate( lesiones= rowSums(across(all_of(paste0("diag", 1:11)), ~ in_lesiones_amplio(.))) > 0 )
suicidio_com_amplio_2nd<-
second_episode_com |>
    mutate( lesiones= rowSums(across(all_of(paste0("diag", 1:11)), ~ in_lesiones_amplio(.))) > 0 )

#_#_#_#_#_#_#_#_#_#_#_
cbind.data.frame(
  cluster= c("Total", "First quarter, MH", "First quarter, SUD", "First semester, MH", "First quarter, comorbidity"),
rbind.data.frame(
format_table_vec(table(factor(todes_suicidio$lesiones, levels = c(FALSE, TRUE)))),
format_table_vec(table(factor(suicidio_1_trim_tsm$lesiones, levels = c(FALSE, TRUE)))),
format_table_vec(table(factor(suicidio_1_trim_tus$lesiones, levels = c(FALSE, TRUE)))),
format_table_vec(table(factor(suicidio_1_sem_tsm$lesiones, levels = c(FALSE, TRUE)))),
format_table_vec(table(factor(suicidio_com$lesiones, levels = c(FALSE, TRUE))))
)
)|>
    (\(df) {
  colnames(df) <- c("cluster", "FALSE", "TRUE"); df
      })() |> rio::export("_output/intrahosp_int_self_harm_by_cluster.xlsx")

#https://pmc.ncbi.nlm.nih.gov/articles/PMC11208976/
##poisoning and toxic effects of drugs and chemicals T36-T65
#adopted to categorize all types of poisonings (T36-T65).
#https://doi.org/10.1002/hsr2.587
cbind.data.frame(
  cluster= c("Total", "First quarter, MH", "First quarter, SUD", "First semester, MH", "First quarter, comorbidity"),
rbind.data.frame(
format_table_vec(table(factor(todes_suicidio_amplio$lesiones, levels = c(FALSE, TRUE)))),
format_table_vec(table(factor(suicidio_1_trim_tsm_amplio$lesiones, levels = c(FALSE, TRUE)))),
format_table_vec(table(factor(suicidio_1_trim_tus_amplio$lesiones, levels = c(FALSE, TRUE)))),
format_table_vec(table(factor(suicidio_1_sem_tsm_amplio$lesiones, levels = c(FALSE, TRUE)))),
format_table_vec(table(factor(suicidio_com_amplio$lesiones, levels = c(FALSE, TRUE))))
)
)|>
    (\(df) {
  colnames(df) <- c("cluster", "FALSE", "TRUE"); df
      })() |> rio::export("_output/intrahosp_poisonings_by_cluster.xlsx")


cbind.data.frame(
  cluster= c("Total", "First quarter, MH", "First quarter, SUD", "First semester, MH", "First quarter, comorbidity"),
rbind.data.frame(
format_table_vec(table(factor(todes_suicidio_2nd$lesiones, levels = c(FALSE, TRUE)))),
format_table_vec(table(factor(suicidio_1_trim_tsm_2nd$lesiones, levels = c(FALSE, TRUE)))),
format_table_vec(table(factor(suicidio_1_trim_tus_2nd$lesiones, levels = c(FALSE, TRUE)))),
format_table_vec(table(factor(suicidio_1_sem_tsm_2nd$lesiones, levels = c(FALSE, TRUE)))),
format_table_vec(table(factor(suicidio_com_2nd$lesiones, levels = c(FALSE, TRUE))))
)
)|>
    (\(df) {
  colnames(df) <- c("cluster", "FALSE", "TRUE"); df
      })() |> rio::export("_output/intrahosp_int_self_harm_by_cluster_2nd_ep.xlsx")

#https://pmc.ncbi.nlm.nih.gov/articles/PMC11208976/
##poisoning and toxic effects of drugs and chemicals T36-T65
#adopted to categorize all types of poisonings (T36-T65).
#https://doi.org/10.1002/hsr2.587
cbind.data.frame(
  cluster= c("Total", "First quarter, MH", "First quarter, SUD", "First semester, MH", "First quarter, comorbidity"),
rbind.data.frame(
format_table_vec(table(factor(todes_suicidio_amplio_2nd$lesiones, levels = c(FALSE, TRUE)))),
format_table_vec(table(factor(suicidio_1_trim_tsm_amplio_2nd$lesiones, levels = c(FALSE, TRUE)))),
format_table_vec(table(factor(suicidio_1_trim_tus_amplio_2nd$lesiones, levels = c(FALSE, TRUE)))),
format_table_vec(table(factor(suicidio_1_sem_tsm_amplio_2nd$lesiones, levels = c(FALSE, TRUE)))),
format_table_vec(table(factor(suicidio_com_amplio_2nd$lesiones, levels = c(FALSE, TRUE))))
)
)|>
    (\(df) {
  colnames(df) <- c("cluster", "FALSE", "TRUE"); df
      })() |> rio::export("_output/intrahosp_poisonings_by_cluster_2nd_ep.xlsx")



#::::::::##::::::::##::::::::##::::::::##::::::::##::::::::##::::::::#
#::::::::##::::::::##::::::::##::::::::##::::::::##::::::::##::::::::##::::::::#
#::::::::##::::::::##::::::::##::::::::##::::::::##::::::::##::::::::#
#
#
rownames_vec <- c(
  "Trastornos mentales orgánicos: F00.0-F09.9",
  "Trastornos por uso de sustancias: F10.0-F19.9",
  "Esquizofrenia: F20.0-F20.9",
  "Otros trastornos psicóticos no afectivos: F21.0-F29.9",
  "Trastornos bipolares: F30.0-F31.9",
  "Trastornos depresivos y otros del estado de ánimo: F32.0-F39.9",
  "Trastornos de ansiedad: F40.0-F49.9",
  "Trastornos de la personalidad: F60.0-F69.9"
)

cbind.data.frame(Total= tot_cie10_clas_2nd[,2],
                 Prim_trim_tsm= second_trim_tsm_clas[,2],
                 Prim_trim_tus= second_trim_tus_clas[,2],
                 Prim_sem_tsm=  second_sem_tsm_clas[,2],
                 Prim_trim_com= second_trim_com_clas[,2]
                 )|>
    (\(df) {
  rownames(df) <- rownames_vec; df
      })() |> 
  rio::export("_output/diagnostic_classification_cie10_following_treatment.xlsx")
  #knitr::kable("markdown", caption= "Clasificación diagnóstica CIE-10")

cbind.data.frame(Total= tot_cie10_clas[,2],
                 Prim_trim_tsm= prim_trim_tsm_clas[,2],
                 Prim_trim_tus= prim_trim_tus_clas[,2],
                 Prim_sem_tsm=  prim_sem_tsm_clas[,2],
                 Prim_trim_com= prim_trim_com_clas[,2]
                 )|>
    (\(df) {
  rownames(df) <- rownames_vec; df
      })() |> 
  knitr::kable("markdown", caption= "Clasificación diagnóstica CIE-10")
2025-03-01: generalSecond episodes, total: 31172025-03-01: TSM 1 semestreSecond episodes, First quarter, MH: 23192025-03-01: TSM 2 trimestresSecond episodes, First semester, MH: 3722025-03-01: ComorbilidadSecond episodes, First quarter, Comorbidity: 1332025-03-01: TUSSecond episodes, First quarter, SUD: 293
Clasificación diagnóstica CIE-10
Total Prim_trim_tsm Prim_trim_tus Prim_sem_tsm Prim_trim_com
Trastornos mentales orgánicos: F00.0-F09.9 100 (1.5) 90 (1.7) 0 (0) 5 (1.3) 5 (2.2)
Trastornos por uso de sustancias: F10.0-F19.9 1293 (19.5) 320 (6.1) 728 (97.1) 35 (8.8) 210 (91.7)
Esquizofrenia: F20.0-F20.9 441 (6.7) 374 (7.1) 0 (0) 47 (11.8) 20 (8.7)
Otros trastornos psicóticos no afectivos: F21.0-F29.9 423 (6.4) 355 (6.8) 0 (0) 30 (7.5) 38 (16.6)
Trastornos bipolares: F30.0-F31.9 411 (6.2) 371 (7.1) 0 (0) 24 (6.0) 16 (7.0)
Trastornos depresivos y otros del estado de ánimo: F32.0-F39.9 2009 (30.3) 1846 (35.2) 0 (0) 130 (32.6) 33 (14.4)
Trastornos de ansiedad: F40.0-F49.9 1082 (16.3) 1004 (19.1) 0 (0) 60 (15.0) 18 (7.9)
Trastornos de la personalidad: F60.0-F69.9 1234 (18.6) 1088 (20.7) 0 (0) 73 (18.3) 73 (31.9)

Tiempo que demora esta sección: 0 minutos

Código
episodes_1_overall<-
df_filled2 |> 
  dplyr::filter(run %in% ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$run) |> 
    dplyr::select(run, diag1, diag2, diag3, diag4, diag5, diag6, diag7, diag8, diag9, diag10, diag11, fecha_egreso_rec_fmt, estab_homo) |> 
    dplyr::group_by(run) |>
    dplyr::summarise(n= n())|>
    dplyr::ungroup()

episodes_1_trim_tsm<-
df_filled2 |> 
  dplyr::filter(run %in% subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, clus_pam_om4=="6623, Un trimestre, TSM(4)")$run) |> 
    dplyr::select(run, diag1, diag2, diag3, diag4, diag5, diag6, diag7, diag8, diag9, diag10, diag11, fecha_egreso_rec_fmt, estab_homo) |> 
    dplyr::group_by(run) |>
    dplyr::summarise(n= n())|>
    dplyr::ungroup()

episodes_1_trim_tus<-
df_filled2 |> 
dplyr::filter(run %in% subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, clus_pam_om4=="6612, Un trimestre, TUS(3)")$run) |> 
    dplyr::select(run, diag1, diag2, diag3, diag4, diag5, diag6, diag7, diag8, diag9, diag10, diag11, fecha_egreso_rec_fmt, estab_homo) |> 
    dplyr::group_by(run) |>
    dplyr::summarise(n= n())|>
    dplyr::ungroup()

episodes_1_sem_tsm<-
df_filled2 |> 
    dplyr::filter(run %in% subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, clus_pam_om4=="6522, Un semestre TSM(1)")$run) |> 
    dplyr::select(run, diag1, diag2, diag3, diag4, diag5, diag6, diag7, diag8, diag9, diag10, diag11, fecha_egreso_rec_fmt, estab_homo) |> 
    dplyr::group_by(run) |>
    dplyr::summarise(n= n())|>
    dplyr::ungroup()

episodes_1_trim_com<-
df_filled2 |> 
  dplyr::filter(run %in% subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, clus_pam_om4=="6574, Comorbilidad un trimestre(2)")$run) |> 
    dplyr::select(run, diag1, diag2, diag3, diag4, diag5, diag6, diag7, diag8, diag9, diag10, diag11, fecha_egreso_rec_fmt, estab_homo) |> 
    dplyr::group_by(run) |>
    dplyr::summarise(n= n())|>
    dplyr::ungroup()


rbind.data.frame(
df_filled2 |> 
  dplyr::filter(run %in% ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$run) |> 
  pull(days_elapsed) |> psych::describe(quant=c(.25,.75)),
df_filled2 |> 
  dplyr::filter(run %in% subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, clus_pam_om4=="6623, Un trimestre, TSM(4)")$run) |> 
  pull(days_elapsed) |> psych::describe(quant=c(.25,.75)),
df_filled2 |> 
dplyr::filter(run %in% subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, clus_pam_om4=="6612, Un trimestre, TUS(3)")$run) |> 
  pull(days_elapsed) |> psych::describe(quant=c(.25,.75)),
df_filled2 |> 
dplyr::filter(run %in% subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, clus_pam_om4=="6522, Un semestre TSM(1)")$run) |> 
  pull(days_elapsed) |> psych::describe(quant=c(.25,.75)),
df_filled2 |> 
dplyr::filter(run %in% subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, clus_pam_om4=="6574, Comorbilidad un trimestre(2)")$run) |> 
  pull(days_elapsed) |> psych::describe(quant=c(.25,.75))
)|>
  (\(df) {
 rownames(df) <- c("Total", "Un trimestre, TSM", "Un trimestre, TUS", "Un semestre, TSM", "Comorbilidad, un trimestre"); df
      })() |> 
  select(-any_of(c("trimmed", "mad", "range", "skew", "kurtosis","se"))) |> 
  knitr::kable("markdown", caption="Días de hospitalización por cluster", digits=2)

rbind.data.frame(
psych::describe(episodes_1_overall$n, quant=c(.25,.75)),
psych::describe(episodes_1_trim_tsm$n, quant=c(.25,.75)),
psych::describe(episodes_1_trim_tus$n, quant=c(.25,.75)),
psych::describe(episodes_1_sem_tsm$n, quant=c(.25,.75)),
psych::describe(episodes_1_trim_com$n, quant=c(.25,.75))
) |> 
  (\(df) {
 rownames(df) <- c("Total", "Un trimestre, TSM", "Un trimestre, TUS", "Un semestre, TSM", "Comorbilidad, un trimestre"); df
      })() |> 
  select(-any_of(c("trimmed", "mad", "range", "skew", "kurtosis","se"))) |> 
  knitr::kable("markdown", caption="Número de episodios por cluster", digits=2)


cat("Número de episodios vs. conglomerado")
data_n_episodes<- 
cbind.data.frame(episodes= c(episodes_1_trim_tsm$n, episodes_1_trim_tus$n, episodes_1_sem_tsm$n, episodes_1_trim_com$n),
cluster= c(rep("MH, Q1", length(episodes_1_trim_tsm$n)), rep("TUS, Q1", length(episodes_1_trim_tus$n)), rep("TUS, 1Sem", length(episodes_1_sem_tsm$n)), rep("Comorbidity", length(episodes_1_trim_com$n)))
)

kruskal_result <- kruskal.test(episodes ~ cluster, data= data_n_episodes)
kruskal_result
#Kruskal-Wallis chi-squared = 575.22, df = 3, p-value < 2.2e-16

dunn_result <- rstatix::dunn_test(data_n_episodes, episodes~cluster, p.adjust.method = "holm")
print(dunn_result)

#:#:#:#:#:#:#:#:#:#:
#:#:#:#:#:#:#:#:#:#:
#:#:#:#:#:#:#:#:#:#:
cat("Hay diferencias por largo de estadía?")
cluster_length_stay<- 
rbind.data.frame(
    cbind.data.frame(cluster="MH, Q1", df_filled2 |> arrange(run, fecha_ingreso) |> group_by(run) |> slice(1) |> ungroup() |> 
        dplyr::filter(run %in% subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, clus_pam_om4=="6623, Un trimestre, TSM(4)")$run) |> 
        pull(days_elapsed)),
    cbind.data.frame(cluster="SUD, Q1", df_filled2 |> arrange(run, fecha_ingreso) |> group_by(run) |> slice(1) |> ungroup() |> 
        dplyr::filter(run %in% subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, clus_pam_om4=="6612, Un trimestre, TUS(3)")$run) |> 
        pull(days_elapsed)),
    cbind.data.frame(cluster="MH, Sem1", df_filled2 |> arrange(run, fecha_ingreso) |> group_by(run) |> slice(1) |> ungroup() |> 
        dplyr::filter(run %in% subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, clus_pam_om4=="6522, Un semestre TSM(1)")$run) |> 
        pull(days_elapsed)),
    cbind.data.frame(cluster="Comorb", df_filled2 |> arrange(run, fecha_ingreso) |> group_by(run) |> slice(1) |> ungroup() |>  
        dplyr::filter(run %in% subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, clus_pam_om4=="6574, Comorbilidad un trimestre(2)")$run) |> 
        pull(days_elapsed)) 
)
colnames(cluster_length_stay) <- c("cluster", "LOS")

kruskal_result_los <- kruskal.test(LOS ~ cluster, data= cluster_length_stay)
kruskal_result_los
#Kruskal-Wallis chi-squared = 290.29, df = 3, p-value < 2.2e-16


dunn_result_los <- rstatix::dunn_test(cluster_length_stay, LOS~cluster, p.adjust.method = "holm")
print(dunn_result_los)

#SUD, Q1 > MH, Q1 > MH, Sem1 ≈ Comorb
Días de hospitalización por cluster
vars n mean sd median min max Q0.25 Q0.75
Total 1 13230 13.41 30.29 6 0 1425 2 16
Un trimestre, TSM 1 9673 11.66 16.63 5 0 475 2 16
Un trimestre, TUS 1 1392 10.01 21.35 3 0 365 1 11
Un semestre, TSM 1 1639 24.11 64.63 9 0 1425 3 24
Comorbilidad, un trimestre 1 526 21.24 57.32 9 0 877 3 25
Número de episodios por cluster
vars n mean sd median min max Q0.25 Q0.75
Total 1 6626 2.00 1.75 1 1 36 1 2
Un trimestre, TSM 1 5248 1.84 1.43 1 1 23 1 2
Un trimestre, TUS 1 750 1.86 1.84 1 1 21 1 2
Un semestre, TSM 1 399 4.11 3.35 3 1 36 2 5
Comorbilidad, un trimestre 1 229 2.30 1.85 2 1 14 1 3
Número de episodios vs. conglomerado
    Kruskal-Wallis rank sum test

data:  episodes by cluster
Kruskal-Wallis chi-squared = 575.22, df = 3, p-value < 2.2e-16

# A tibble: 6 × 9
  .y.      group1  group2    n1    n2 statistic         p     p.adj p.adj.signif
* <chr>    <chr>   <chr>  <int> <int>     <dbl>     <dbl>     <dbl> <chr>       
1 episodes Comorb… MH, Q1   229  5248     -4.66 3.11e-  6 6.21e-  6 ****        
2 episodes Comorb… TUS, …   229   399     10.8  3.79e- 27 1.52e- 26 ****        
3 episodes Comorb… TUS, …   229   750     -5.29 1.25e-  7 3.75e-  7 ****        
4 episodes MH, Q1  TUS, …  5248   399     23.3  5.62e-120 3.37e-119 ****        
5 episodes MH, Q1  TUS, …  5248   750     -2.16 3.09e-  2 3.09e-  2 *           
6 episodes TUS, 1… TUS, …   399   750    -20.9  8.45e- 97 4.23e- 96 ****        
Hay diferencias por largo de estadía?
    Kruskal-Wallis rank sum test

data:  LOS by cluster
Kruskal-Wallis chi-squared = 181.96, df = 3, p-value < 2.2e-16

# A tibble: 6 × 9
  .y.   group1   group2      n1    n2 statistic        p    p.adj p.adj.signif
* <chr> <chr>    <chr>    <int> <int>     <dbl>    <dbl>    <dbl> <chr>       
1 LOS   Comorb   MH, Q1     229  5248     -4.55 5.44e- 6 1.09e- 5 ****        
2 LOS   Comorb   MH, Sem1   229   399      1.69 9.04e- 2 9.04e- 2 ns          
3 LOS   Comorb   SUD, Q1    229   750     -8.41 4.24e-17 1.70e-16 ****        
4 LOS   MH, Q1   MH, Sem1  5248   399      8.61 7.05e-18 3.52e-17 ****        
5 LOS   MH, Q1   SUD, Q1   5248   750     -8.39 4.67e-17 1.70e-16 ****        
6 LOS   MH, Sem1 SUD, Q1    399   750    -12.5  6.77e-36 4.06e-35 ****        

Tiempo que demora esta sección: 0 minutos

Luego vemos la clasificación de PPOO por cluster

Código
cat("Traemos la base de datos con todos los clasificados como PPOO\n")
filtered_df_csv <- readr::read_csv("filtered_df.csv", col_types = readr::cols(...1 = readr::col_skip()))
colnames(filtered_df_csv)<- c("rn", "run")
nrow(filtered_df_csv)
#[1] 1687190
invisible("Quienes tienen un registro RSH o en el histórico una autoidentificación por MINSAL")
ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$ppoo_minsal_y_rsh_2010 <- 
ifelse(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$run %in%  filtered_df_csv$run,1,0)

ci_cya_conadi<-readr::read_csv("cya_conadi_o_ci_conadi.csv")
nrow(ci_cya_conadi)
#[1] 1037607

cat("Quienes tienen al menos uno?\n")
filtered_df_csv |> 
  tidytable::inner_join(ci_cya_conadi, by=c("run"="RUN"), multiple="first") |> 
  nrow()
#[1] 800271
scales::percent(800271/9646325, accuracy=.1)

cat("Sólo CONADI\n")
filtered_df_csv |> 
  tidytable::right_join(ci_cya_conadi, by=c("run"="RUN"), multiple="first") |> 
  filter(is.na(rn)) |> 
  nrow()
#[1] 237336
scales::percent(237336/9646325, accuracy=.1)


cat("Sólo RSH o autodentificación histórico\n")
filtered_df_csv |> 
  tidytable::left_join(ci_cya_conadi, by=c("run"="RUN"), multiple="first") |> 
  filter(!is.na(rn)) |> 
  nrow()
#[1] 2129654
scales::percent(2129654/9646325, accuracy=.1)

invisible("SI tiene un registro CONADI CyA o CI, entonces es 1")
ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$ci_cya_conadi <- 
ifelse(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$run %in%  ci_cya_conadi$RUN,1,0)

cat("Tabla de interesección entre pueblos originarios y CONADI, histórico (2005-)\n")
table(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$ppoo_minsal_y_rsh_2010,
ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$ci_cya_conadi)
#      0    1
# 0 5310  137
# 1  754  425
rm(ci_cya_conadi)
rm(filtered_df_csv)

scales::percent(table(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$ppoo_minsal_y_rsh_2010,
ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$ci_cya_conadi)[[4]] / nrow(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens), accuracy=.1)

cat("CONADI y 2005- MINSAL/ RSH: \n")
scales::percent(table(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$ppoo_minsal_y_rsh_2010,
      ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$ci_cya_conadi)[[4]]/ nrow(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens), accuracy=.1)

cat("Al menos uno (inclusivo): \n")
scales::percent(1-(table(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$ppoo_minsal_y_rsh_2010,
      ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$ci_cya_conadi)[[1]]/ nrow(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens)), accuracy=.1)


cat("Sólo en RSH o MINSAL 2005- : \n")
scales::percent(sum(table(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$ppoo_minsal_y_rsh_2010,
      ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$ci_cya_conadi)[c(2,4)])/ nrow(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens), accuracy=.1)



cat("ASociación con pertenencia a conglomerados, nueva agrupación\n")
janitor::chisq.test(df_filled2[,c("run","glosa_pueblo_originario")] |> 
        dplyr::left_join(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens[,c("run", "clus_pam_om4")], by="run", multiple="first") |> 
        janitor::tabyl(glosa_pueblo_originario, clus_pam_om4))
# X-squared = 128.12, df = 24, p-value = 3.399e-16
#
#
cat("Restringiendo el análisis a quienes reportan MINSAL Rapa Nui, Mapuche y Ninguno\n") 

df_filled2[, c("run", "glosa_pueblo_originario")] |>
  dplyr::left_join(
    ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens[, c("run", "clus_pam_om4")],
    by = "run", multiple = "first"
  ) |>
  dplyr::filter(glosa_pueblo_originario %in% c("RAPA NUI (PASCUENSE)", "MAPUCHE", "NINGUNO")) |>
  janitor::tabyl(glosa_pueblo_originario, clus_pam_om4) |>
  (\(df) {
    list(
      chisq = janitor::chisq.test(df),
      percentages = df |>
        janitor::adorn_percentages("col") |>
        dplyr::mutate(across(2:5, ~round(., 2)))
    )
  })()

invisible("No exclusivo de la clasificación por conglomerados, sino de las trayectorias en general y las matrices de distancia")
#https://cran.r-project.org/web/packages/TraMineRextras/TraMineRextras.pdf
seqcompare_sex_quarter_om<-
seqCompare(States_Wide.seq_quarter_t_prim_adm, group=ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$glosa_sexo, method="OM", sm=costmatrix_quarter, seed= 2125, s=1e1, stat="all")
#           LRT    p-value BIC diff. Bayes Factor (Avg) Bayes Factor (From Avg BIC)
# [1,] 3.723906 0.07729539 0.7281733           2.140152                    1.439199
seqcompare_sex_quarter_lcs<-
seqCompare(States_Wide.seq_quarter_t_prim_adm, group=ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$glosa_sexo, method="LCS", sm=costmatrix_quarter, seed= 2125, s=1e1, stat="all")
#           LRT    p-value BIC diff. Bayes Factor (Avg) Bayes Factor (From Avg BIC)
# [1,] 3.537305 0.08879071 0.5415731           2.120956                    1.310995

seqcompare_ppoo_quarter_om<-
seqCompare(States_Wide.seq_quarter_t_prim_adm, group=ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$inclusivo_real_historico, method="OM", sm=costmatrix_quarter, seed= 2125, s=1e1, stat="all")
#  Currently seqLRT supports only 2 groups!
#           LRT    p-value BIC diff. Bayes Factor (Avg) Bayes Factor (From Avg BIC)
# [1,] 3.321524 0.08714022  0.325792           1.479436                    1.176914
seqcompare_ppoo_quarter_lcs<-
seqCompare(States_Wide.seq_quarter_t_prim_adm, group=ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$inclusivo_real_historico, method="LCS", sm=costmatrix_quarter, seed= 2125, s=1e1, stat="all")
#           LRT    p-value BIC diff. Bayes Factor (Avg) Bayes Factor (From Avg BIC)
# [1,] 3.214252 0.09793892   0.21852           1.456759                    1.115452
# 


#dt_df_filled2 #se supone que en este se eliminan los registros otros del primer evento hosp no TUS/MH
#también lo hace para mi base según un_inv_ii2_25.qmd
glosa_pueblo_originario_rec <- 
  df_filled2[, c("run", "glosa_pueblo_originario")] |> 
  left_join(
    ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens[, c("run", "clus_pam_om4", "ppoo_minsal_y_rsh_2010", "ci_cya_conadi")],
    by = "run",
    multiple = "first"
  ) |> 
  mutate(
    glosa_pueblo_originario_rec = case_when(
      glosa_pueblo_originario == "NINGUNO" & (ci_cya_conadi ==1 | ppoo_minsal_y_rsh_2010==1)~ "DESCONOCIDO",
      glosa_pueblo_originario == "NINGUNO" ~ "NINGUNO",
      grepl("RAPA|MAPU", glosa_pueblo_originario) ~ "RAPA NUI o MAPUCHE",
      TRUE ~ "RESTO"
    ),
    pueblo_bin = case_when(
      glosa_pueblo_originario_rec == "RAPA NUI o MAPUCHE" ~ "Mapuche o Rapa Nui",
      glosa_pueblo_originario_rec %in% c("DESCONOCIDO", "NINGUNO", "RESTO") ~ "Otro o ninguno"
    )
  ) |> 
  group_by(run) |> 
  summarise(
    sum_ppoo = sum(grepl("Mapuche o Rapa Nui", pueblo_bin)),
    .groups = "drop"
  ) |> 
  mutate(
    sum_bin_ppo = ifelse(sum_ppoo > 0, 1, 0)
  ) |> 
  pull(sum_bin_ppo)

glosa_pueblo_originario_rec2 <- 
  ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens[, c("run", "clus_pam_om4", "ppoo_minsal_y_rsh_2010", "ci_cya_conadi")] |> 
  left_join(
    df_filled2[, c("run", "glosa_pueblo_originario")],
    by = "run",
    multiple = "first"
  ) |> 
  mutate(
    glosa_pueblo_originario_rec = case_when(
      glosa_pueblo_originario == "NINGUNO" & (ci_cya_conadi ==1 | ppoo_minsal_y_rsh_2010==1)~ "DESCONOCIDO",
      glosa_pueblo_originario == "NINGUNO" ~ "NINGUNO",
      grepl("RAPA|MAPU", glosa_pueblo_originario) ~ "RAPA NUI o MAPUCHE",
      TRUE ~ "RESTO"
    ),
    pueblo_bin = case_when(
      glosa_pueblo_originario_rec == "RAPA NUI o MAPUCHE" ~ "Mapuche o Rapa Nui",
      glosa_pueblo_originario_rec %in% c("DESCONOCIDO", "NINGUNO", "RESTO") ~ "Otro o ninguno"
    )
  ) |> 
  group_by(run) |> 
  summarise(
    sum_ppoo = sum(grepl("Mapuche o Rapa Nui", pueblo_bin)),
    .groups = "drop"
  ) |> 
  mutate(
    sum_bin_ppo = ifelse(sum_ppoo > 0, 1, 0)
  ) |> 
  pull(sum_bin_ppo)


cat("Qué ocurre si utilizamos la claisficación del primer eventos hospitalarios en vez de cualquier desde 2018 en adelante?")
round(prop.table(table(glosa_pueblo_originario_rec2, glosa_pueblo_originario_rec),2)*100,1)

print("Estaríamos elimnando un 18% de casos de registros en otro momento")

glosa_pueblo_originario_rec_num<-as.numeric(factor(glosa_pueblo_originario_rec))-1

seqcompare_ppoo_quarter_om_ppoo_rec<-
TraMineRextras::seqCompare(States_Wide.seq_quarter_t_prim_adm, group=glosa_pueblo_originario_rec_num, method="OM", sm=costmatrix_quarter, seed= 2125, s=1e1, stat="all")# s= Integer. Default 100. The size of random samples of sequences. When 0, no sampling is done.
Traemos la base de datos con todos los clasificados como PPOO
[1] 1687190
[1] 1037607
Quienes tienen al menos uno?
[1] 800271
[1] "8.3%"
Sólo CONADI
[1] 237336
[1] "2.5%"
Sólo RSH o autodentificación histórico
[1] 2129654
[1] "22.1%"
Tabla de interesección entre pueblos originarios y CONADI, histórico (2005-)
   
       0    1
  0 5310  137
  1  754  425
[1] "6.4%"
CONADI y 2005- MINSAL/ RSH: 
[1] "6.4%"
Al menos uno (inclusivo): 
[1] "19.9%"
Sólo en RSH o MINSAL 2005- : 
[1] "17.8%"
ASociación con pertenencia a conglomerados, nueva agrupación

    Pearson's Chi-squared test

data:  janitor::tabyl(dplyr::left_join(df_filled2[, c("run", "glosa_pueblo_originario")],     ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens[,         c("run", "clus_pam_om4")], by = "run", multiple = "first"),     glosa_pueblo_originario, clus_pam_om4)
X-squared = 128.12, df = 24, p-value = 3.399e-16

Restringiendo el análisis a quienes reportan MINSAL Rapa Nui, Mapuche y Ninguno
$chisq

    Pearson's Chi-squared test

data:  df
X-squared = 88.475, df = 6, p-value < 2.2e-16


$percentages
 glosa_pueblo_originario 6623, Un trimestre, TSM(4) 6612, Un trimestre, TUS(3)
                 MAPUCHE                       0.02                       0.04
                 NINGUNO                       0.98                       0.96
    RAPA NUI (PASCUENSE)                       0.00                       0.00
 6522, Un semestre TSM(1) 6574, Comorbilidad un trimestre(2)
                     0.02                               0.01
                     0.96                               0.98
                     0.01                               0.01

Qué ocurre si utilizamos la claisficación del primer eventos hospitalarios en vez de cualquier desde 2018 en adelante?                            glosa_pueblo_originario_rec
glosa_pueblo_originario_rec2     0     1
                           0 100.0  18.8
                           1   0.0  81.2
[1] "Estaríamos elimnando un 18% de casos de registros en otro momento"

Tiempo que demora esta sección: 0.2 minutos

Generamos un gráfico de PPOO por cada conglomerado.

Código
ppoo_clus_pre_pam_om4_q<-
  df_filled2[,c("run","glosa_pueblo_originario")] |> 
  dplyr::left_join(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens[,c("run", "clus_pam_om4","ci_cya_conadi", "ppoo_minsal_y_rsh_2010")], by="run", multiple="first") |> 
  dplyr::mutate(glosa_pueblo_originario_rec= dplyr::case_when(glosa_pueblo_originario == "NINGUNO" & (ci_cya_conadi ==1 | ppoo_minsal_y_rsh_2010==1)~ "DESCONOCIDO", T~glosa_pueblo_originario)) |> 
  janitor::tabyl(glosa_pueblo_originario_rec, clus_pam_om4) |> 
  janitor::adorn_percentages("row")

invisible("2025-04-13")
cat("Sólo RAPA NUI y MAPUCHE (ver por RUN, al menos una observación que se identifique RAPA NUI o MAPUCHE)\n")
ppoo_clus_pre_pam_om4_q_act<-
  df_filled2[,c("run","glosa_pueblo_originario")]|> 
  dplyr::left_join(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens[,c("run", "clus_pam_om4","ci_cya_conadi", "ppoo_minsal_y_rsh_2010")], by="run")|> 
  dplyr::mutate(glosa_pueblo_originario_rec= dplyr::case_when(glosa_pueblo_originario == "NINGUNO" & (ci_cya_conadi ==1 | ppoo_minsal_y_rsh_2010==1)~ "DESCONOCIDO", T~glosa_pueblo_originario)) |> 
  group_by(run, clus_pam_om4)|>
  summarise(sum_ppoo= sum(grepl("RAPA|MAPU", glosa_pueblo_originario_rec)), .groups="drop")|>
  ungroup()|> 
  mutate(sum_bin_ppo= ifelse(sum_ppoo>0, 1, 0))|>
  janitor::tabyl(sum_bin_ppo, clus_pam_om4)
janitor::chisq.test((ppoo_clus_pre_pam_om4_q_act))
#X-squared = 6.2657, df = 3, p-value = 0.09938

cat("Sólo RAPA NUI (ver por RUN, al menos una observación que se identifique RAPA NUI)\n")
ppoo_clus_pre_pam_om4_q_rapa<-
  df_filled2[,c("run","glosa_pueblo_originario")]|> 
  dplyr::left_join(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens[,c("run", "clus_pam_om4","ci_cya_conadi", "ppoo_minsal_y_rsh_2010")], by="run")|> 
  dplyr::mutate(glosa_pueblo_originario_rec= dplyr::case_when(glosa_pueblo_originario == "NINGUNO" & (ci_cya_conadi ==1 | ppoo_minsal_y_rsh_2010==1)~ "DESCONOCIDO", T~glosa_pueblo_originario))|> 
  group_by(run, clus_pam_om4)|>
  summarise(sum_ppoo= sum(grepl("RAPA", glosa_pueblo_originario_rec)), .groups="drop")|>
  ungroup()|> 
  mutate(sum_bin_ppo= ifelse(sum_ppoo>0, 1, 0))|>
  janitor::tabyl(sum_bin_ppo, clus_pam_om4)

janitor::fisher.test((ppoo_clus_pre_pam_om4_q_rapa))
#p-value = 0.009065
cat("son 12 casos!\n")

cat("______________________\n")
cat("ESTE ES EL REPORTE QUE ESTÁ PUBLICAODO AL 2025-05-16 EN EL ARTICULO\n")
cat("______________________\n")
ppoo_clus_clasificaciones<-
df_filled2[, c("run", "glosa_pueblo_originario")] |>
  left_join(
    ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens[, c("run", "clus_pam_om4","ci_cya_conadi", "ppoo_minsal_y_rsh_2010")], 
    by = "run"
  ) |>
  mutate(glosa_pueblo_originario_rec = if_else(
    glosa_pueblo_originario == "NINGUNO" & (ci_cya_conadi ==1 | ppoo_minsal_y_rsh_2010==1), "DESCONOCIDO",
    glosa_pueblo_originario
  )) |>
  group_by(run) |>
  summarise(
    tiene_otro_po = any(grepl("AYMARA|COLLA|DIAGUITA|KAWÉSQAR|RAPA NUI|YAGÁN|OTRO", glosa_pueblo_originario_rec)),
    tiene_mapuche = any(grepl("MAPUCHE", glosa_pueblo_originario_rec)),
    tiene_ninguno = any(glosa_pueblo_originario_rec == "NINGUNO"),
    tiene_desconocido = any(glosa_pueblo_originario_rec == "DESCONOCIDO"),
    .groups = "drop"
  ) |>
  mutate(clas_por_run = case_when(
    tiene_mapuche ~ "Mapuche",
    !tiene_mapuche & tiene_otro_po ~ "Otros reportados (no mapuche)",
    tiene_ninguno & !tiene_otro_po & !tiene_mapuche ~ "Ninguno puro",
    tiene_desconocido & !tiene_ninguno & !tiene_otro_po & !tiene_mapuche ~ "Desconocido puro", T~NA_character_
  )) |>
  janitor::tabyl(clas_por_run, show_na = T) |>
     mutate(clas_por_run= factor(clas_por_run, levels= c("Ninguno puro", "Desconocido puro", "Otros reportados (no mapuche)", "Mapuche")))|> 
    arrange(clas_por_run)

ppoo_clus_clasificaciones|>
  mutate(percent=round(percent*100, 1)) |>
  (\(df) {
  if (interactive()) {df|> rio::export("clipboard")}
  knitr::kable(df, caption="Porcentajes por columna, conglomerado vs. PPOO")
  })()


ppoo_clus_pre_pam_om4_q_clasificaciones<-
df_filled2[, c("run", "glosa_pueblo_originario")] |>
  left_join(
    ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens[, c("run", "clus_pam_om4","ci_cya_conadi", "ppoo_minsal_y_rsh_2010")], 
    by = "run"
  ) |>
  mutate(glosa_pueblo_originario_rec = if_else(
    glosa_pueblo_originario == "NINGUNO" & (ci_cya_conadi ==1 | ppoo_minsal_y_rsh_2010==1), "DESCONOCIDO",
    glosa_pueblo_originario
  )) |>
  group_by(run, clus_pam_om4) |>
  summarise(
    tiene_otro_po = any(grepl("AYMARA|COLLA|DIAGUITA|KAWÉSQAR|RAPA NUI|YAGÁN|OTRO", glosa_pueblo_originario_rec)),
    tiene_mapuche = any(grepl("MAPUCHE", glosa_pueblo_originario_rec)),
    tiene_ninguno = any(glosa_pueblo_originario_rec == "NINGUNO"),
    tiene_desconocido = any(glosa_pueblo_originario_rec == "DESCONOCIDO"),
    .groups = "drop"
  ) |>
  mutate(clas_por_run = case_when(
    tiene_mapuche ~ "Mapuche",
    !tiene_mapuche & tiene_otro_po ~ "Otros reportados (no mapuche)",
    tiene_ninguno & !tiene_otro_po & !tiene_mapuche ~ "Ninguno puro",
    tiene_desconocido & !tiene_ninguno & !tiene_otro_po & !tiene_mapuche ~ "Desconocido puro", T~NA_character_
  )) |>
  janitor::tabyl(clas_por_run, clus_pam_om4, show_na = T)

janitor::adorn_percentages(ppoo_clus_pre_pam_om4_q_clasificaciones, "col")|> 
    mutate_if(is.numeric, ~round(.*100, 1)) |> mutate(clas_por_run= factor(clas_por_run, levels= c("Ninguno puro", "Desconocido puro", "Otros reportados (no mapuche)", "Mapuche")))|> 
  arrange(clas_por_run)|>
  (\(df) {
  if (interactive()) {df|> rio::export("clipboard")}
  knitr::kable(df, caption="Porcentajes por columna, conglomerado vs. PPOO")
  })()

janitor::fisher.test(ppoo_clus_pre_pam_om4_q_clasificaciones, simulate.p.value=T, B=1e5)
#p-value = 0.01


chisq.posthoc.test(ppoo_clus_pre_pam_om4_q_clasificaciones[,2:5],simulate.p.value=T, B=1e5)|> 
  (\(df) { dplyr::mutate_at(df, 3:ncol(df), ~ round(as.numeric(gsub("\\*", "", .)), 3))
  })()|>
  group_by(Dimension)|>
  (\(df) { summarise(df, across(2:(ncol(df)-1), ~ paste0(first(sprintf("%1.2f", .)), " (p=", last(sprintf("%1.3f", .)), ")")))
  })()|>
  (\(df) { dplyr::mutate_at(df, 2:length(names(df)), ~ gsub("p\\=0.000)", "p<0.001)", .))
  })()|>
  mutate(Dimension= ppoo_clus_pre_pam_om4_q_clasificaciones[,1]) |> 
  mutate(Dimension= factor(Dimension, levels= c("Ninguno puro", "Desconocido puro", "Otros reportados (no mapuche)", "Mapuche"))) |> 
  arrange(Dimension) |>
  mutate(Dimension= as.character(Dimension)) |> 
  knitr::kable("markdown", caption = "Comparación post-hoc, conglomerado-PPOO autorreporte")

cat("Tampoco resulta significativo en https://adaptivedesignstrial.shinyapps.io/posthoc/\n")

cat("______________________\n")
cat("______________________\n")
neg_sil_width<- c("020ecfb87667825f8c2ca2273fec57a50789c95ca28374e473057a01a54abcf0", "03f170dac90813987aad559e4d6597e5d751111a5e143a4b4c7b2614bd63fa6a", "0b1ff2a5c8ec1a6e4aa32187670f38943bf7f7dfeedbf496173d60f4fef580f0", "0c2cd69046da92051635be4c1f2fe5364e4bcc8297a675e1a3b0a599fe28f6e1", 
"1075291d2c731cc89eb044ed92de863d291246e4c41972573fd552d941af53e9", 
"11162ea02d506bc1b91d8fd95447721054ff78437763db0a31ab461c992dd735", 
"172cdb27864fbfde67915a288d1c84024603f40a2133c0681d5adb9c87462616", 
"19e5ed0633d9dd89c82f5bd8f1ecc7f5079609760a9d4c3b3a829aa2b2c9d856", 
"1c4cbc882476901ab8bf59c3ecf3eb181b1996da9a325be05116d9a459bc79b1", 
"1c7aa780a03a99c1222b77d519a0b12625f821a0fb8d95caf5f58b555ff75e9f", 
"1dbdb6ef97104f31ecdcaa9d9048fe2b5442f5504ab0d047c9359e0a650ced1d", 
"1e249a0778e2b57f5c2d63cd493e174745aad47966e9b498829bb1b3df69d33f", 
"1f4ac6e6ce2f0ce1b867e308cc3dcda821b1eee6c6c14335e2006d9a3318e25a", 
"1fc36751012ff26d8253fe8f05962779280ba9cfb3e767f0288007ab563d9118", 
"216e8ff4324aab768dcbf8161d78619ee5c54686259b922a26aec69b948e695e", 
"220d4b6ce95f6736e1aa75326e40128abd3bccbabee97a642dd30bccb9eb5023", 
"227db9a09dc4cb4925cfc33660251847b72180ec6eca8bb855dfdbce9b11daf1", 
"24026cea649eb63322019a011427de57dbf64bfc8b6b880ab3071297ac882f39", 
"271a95ec7ccbe6966089f7851cc7041f1b2ee8021b8e3261cce981bf64de329a", 
"2a11c1669370064be8f41ac60334f3a559aadaac871b15b4fcbe0ce7d9242306", 
"2b732d5a24ecdc09f8aa8b8daf51d9f58d3d528ea44b701cb620287513dc1261", 
"2c78585d5e62628802671abeb3ddc41ffda691fe2fe7fb459685be67de899864", 
"2c8ec64b3c6ab90efa37297b6ea50abab1b33944b7291e58165357084ceba3c4", 
"3172a1274529f7e88293faf08d7ac5ec54c6268a94a6a71114217c6f73a6d8ef", 
"3388b29d297eb59bb409ba7b6e9c006f7f099ee724e7fa38cff9bb1d520906ab", 
"35c543f49f2b69898871d8c039fc790d98a2fc54380cee1afab1f7c7d525cb67", 
"371ac171d1a36e5657cf76d27d897d7db2c5eebc54f922d962a001ccfd13a6f9", 
"3afb543ec0fc5046f39441a37a97a7df7b93fdeaa35d25095f0ad415bdc45c0d", 
"3d8a5ff9226706a7e8de03745582bd578e9d777a5f57f920e3a688f41a50bef9", 
"3e06416db73cfb10effdb914a749091d1e2a65629f38fbbc4532710cebcca77d", 
"3f1e7584408d6ee4a1ff810efbb8708d2f2be1ddaa467f36ba202e597453b1d0", 
"3f5be0a18bd23db42f6859c7421701b7257450730bc1636cb22ed10cc6393618", 
"417434ff805f8c44cb5e12621f60e35d33189d3ebbf98903a3d2c031abda6f4e", 
"42e38c995fac0b4f1c42f7609ddedadf7b048a402cac0de4e43aa91ce684bf40", 
"43b4ce7106602a347270f942ac233f246e30556d4ccce307c08da440e48224d5", 
"45acd64b3e874e68334d01dc189ca0e43bcae466edfeb68d2cf588fb1a6d88d1", 
"45b18e2462d5295d0aec2fe4c6fbfda9d3ab27eff26feff396a61583e90d98ca", 
"478f0501656873cb8db4ee1494178e872867c376e5f738ecae9f4346f60c55cb", 
"4882801f8b7cee71c0b95c7cdd88524317cd0c317e0cb58fdc825973654ffd2d", 
"48cb07721dd4dbed3e6d59899773435710cb82aa385f6b50229c4b49706ed36e", 
"4aea5e1a635c93fecd533e54094a2816035b06880f613a8d7b58087654a05654", 
"4b02cd756cb9c2cd54a1ce16f08af06b652188d108cf3e4b8de2b6bbc640a640", 
"50a981e4c68fffe61ef85afdfc9caa9ed334e054eeb1ac0b0abc9f64e26286e8", 
"511a7e2b5d8a98febc1788bef888fa1e802451137e6aece06bc0f1c521122333", 
"51c85b64a4f425a94f4bc01cbb88e5ef00885ded42febb61c2ee46a1847598bd", 
"5251fa85e010ccaa04cbe0b486b6831a039819519004f2cba36cc5eb0fbd504e", 
"5a7da92a90ea18a147b3917dff6e7cb6044970ca372382104769d432235c6bc4", 
"5b6b1a027a12aa5dfc4865dc4c3cc73dfd298ebfe29865f7d68a83d4c4cef075", 
"5cbe163a4e62a98d82a35129cc30c8f37a0fa1542587a880a7a7759ed8228309", 
"6214c3a3c12a86ba71cf347765257a255b1bbef34322713e66d403775ad600d7", 
"62417fd6a719c8ab4abe7da3f7273c7df3b33df38b5442220117e9dccfe997db", 
"63f098f41f2618fe82009a5aaf2729b21414e3262c32a63c531f2a74513f3eaa", 
"64f85f102b1b48d5802874f6b24ff3094f8845f061966a33f4be920f1737c019", 
"66d9d910c5c909b36cb0ae7fe5be5e35465733281c0654de3b6d543395dc0d51", 
"689ac87a0f71e0121efce359fea86dc326dd83b5541ef72a5f037bc343a5afc9", 
"69c4e81e3d883c15aed48c10f75483f9d77b769154c7131bcda53ae7ec8f83c5", 
"6a1bf4562be977b90b61f3d227150cc4318ff6867e2aa6b7e3e56cc12fa980f2", 
"6c5c40557de8bf048645f341704591d069759ba2888209c05c06a7f5d1154f65", 
"6ce14e5d3aad1ad104ad392a6b433674349f9490aefafe6fc53cd21c57ddcbc4", 
"71be067f52d984813d7f34aa8a335e82725f7f132a0976e87790aa6286b34f50", 
"753743e9cdcfdc6583f1a2fe537e3ae886827e6aabf8231976544477a92153f1", 
"75400455db911006ae631da57b0c40acadc219352e35e8cb1b62e86469e24d69", 
"7568556ce276ca6018af6159618cdb0c0c00051a8d6c49e0bd580ff0a40cd48e", 
"76b24534fa10468c20cee7ae77557ddfd6e658bbdae310e8bb6397461d5cec90", 
"7751acaa52c7ec8bfecce109c89dd0c13c275230d091085520892882fb998855", 
"7a555e3a9358d121da82c734e94f281e2333a69d4bb5cc2be8f0f58449c1d72d", 
"7c1af816759cbd3a63dd90472cea923b2bb510489002927b0ee90d2a13884382", 
"815e814acf129e1f8c75b94ee20ea8d63e83a20918ad471c6cdb35d1f3f3ed16", 
"82b18190df1a84ba755f898bd2246305f9ace41d6cb0bd3b780090b903f3dd31", 
"83d33cca6c417496f198ee29fc4e3b97db1563797b2b71828a4c388bdcb0acb2", 
"855e1ea9dfa58bb958b8c5d8a11306dc2ae15348fecea7654a18cbd0b27bdcff", 
"87d7871b1205ae513c858cf4c18d97b57be5594cc9194b8c3197739941ee2992", 
"8845e5c711b24d7af54ef4684225cbc739f9c4fb7674c8688a5279a42f0f71bc", 
"8aabbf007157a2a2bb2188316569361ae6604811996d6c3ba4ddef2ff295f439", 
"8fa5a24fed601395d6bd103a3dcf55d662c5c2f7193f22aed6bf52e352222cbf", 
"902d776b5dffc2d361ea537a5466c80a7b12e46531e0bc3ac78567185061a920", 
"909ab824b3e52a50ec9143933feb379157651e7df0d181bbc50b975c12f7d12e", 
"91868b47d78b8e8992b64686b64b60f578017ce71d6c169ee41900af8c33f482", 
"923c86125fe398217325254e9784f917a2c46b99ccae372fb5a954072069d3a7", 
"94014e288cdd4ec2d9355a9c4e5815b73da692ea8853bb1dc4b5194c49caf96d", 
"94bcedbf2f02f5d1dd392c891b8a30d76254198526af987597dc29cb571a3a45", 
"9524b1e9764ed7f79ed4ba5d7d88035d46716baa1acee79aa79cd044f6fe9db9", 
"96532d98714949a7940350524df68d9a90d2a4fa0a3b6f11f003f8cd89f8f526", 
"98142d43d5a6da0d4e74c8f401aa4bec6c15a6247572032189f292fd92b70b2b", 
"9b5b1fdc78ef1ba5a24ed6ba38f27573aa98b48f21865f3a3c72a09ad1540e6e", 
"9d5ba8dca2b62e8ade5ecaa75178d2ccba815f04a810e83e9f10deb82a27dd66", 
"9d8a06d4f6b5c628f07a862fb25b35c62a2cbaaa631def3e0ce50b1a483d8a91", 
"9f65df12801f4eafeaa51cf33beeef9dfcbc28f5c526726a71e1233053843461", 
"a131725ce6d5436eb2226b1f7ab9e65386cad9e6ddf9097a4add0baa37937568", 
"a387013e998b1fb44a3147dc5d45038c76c3605a32e23bc48ef3f533ba7c01d0", 
"a534e423c77776a0f9f65b3137b62e2d8ca5fc3362e41265a6b128979e9230d4", 
"a57abb6ecfbc785de04acef89a8c8bf8ddc2a1821901eef027898ea07338afed", 
"a663b3eb70c7ac37f38eb44be53f2e21bcce475e13bffab4a07d587994caf512", 
"a679b98ea92e727c2ba3485198ff11bb77f9db1fb7cd5d11c5045db9766ea228", 
"a7991f9634e16c5594fd8d0af28eb9a3269d6ecc8b1d414ee66b27d0d5b18049", 
"ad4bd4818c1b91f92de90fa559e046f0574da50c90bd00488c98895104205291", 
"ad82ee5c2b1132d8d3c6035c02b2bf06614f4d370c145381fbc8f35acf3346bb", 
"ae841a5d3c99874360854f506994ce760a7f20884dcd54395efd570aae1453d1", 
"af0a1c3dbf06a1b95e3f88e3f98e5a1b696b96eca030e42856a34e5efe3924e9", 
"b07f12fc76d6ffae6f7180bec95895f91a2913eae1776d5678c68d61cb9a7e5c", 
"b2d3c4dcb720d828bde1760bdb5875a057e9c10649b3bbe9e6e22a4e66156db7", 
"b36f131c4ad7c16bffef5751d763a6bdde769c75b951cd9025e807e1761adb80", 
"b43dc12b6eb11071274f964bca097a174d62e8cfb623f3451c5cac5ff8d6f368", 
"b67c2ddc3bd9dcc376c1678f230c9ab162c111b743841f5474c8094db62ca43d", 
"b7195a465147fb22e12282c36b76a18ac1de0dae3cfaebcd9328df88f8976dfd", 
"b9e86440342f3c13f5ee3eea90a08d1a9d243f60f2f37e2cb382162b1f419325", 
"bb545866694f35de7ecf6e7978929eaafcb7a3c1a68854fe05a3d35981e36742", 
"be1a75fc5a9248df594f2dfb4fbb32e27c94d4a01ba569ef294e215014906d5f", 
"c081127dc63ef929854188913c230c1a734598848f5790985adf8bc1c73722de", 
"c231e0cccdbcccc8794b8c8d543344c36af10d31fc9f7e038e42311d87a91c2b", 
"c2fad96d3ee7df1be8101368610f413eb47d4f7e3477fea15498e97a4336f4d8", 
"c434e31ddba8ff116d651b3887a5fc9f6b7c17992ef74057d958cf8313a3df13", 
"c45846d4d024a84cbc5a9340fba58b97f7b7a14d12efa34258d7b6a10ab7e502", 
"c6adf196d077efa992b672b5597da5a335a64ba2c61a19a319845373e8e90368", 
"c94d6a040b9e1cbe26c8cfa561d715752500434b4d6fe795f48b67ff94af1ec3", 
"cca372764eaee50190e1440c551f8f9943e3e2600882e89d0a262620767aee3f", 
"ccaf671987cda2729baae792416c2687a0a1d746e5aad164fa76f0259e6f1677", 
"cf19b5fb91ab6cedd4a5189a792ecc390a748be3470ef34ca90acc7f353526eb", 
"cfd4266a2787901e3b704687e758122063a15bf4478d044c75a6842192c2584a", 
"cfd4c640f5049bf5d85aef708b8c505bd7c3092df916a7ac5a4182ffb532e44b", 
"d173965cf02673b00593930d9b9cb3d8ab56b05912119dc2d5395536d7f8ae55", 
"d3730d2a8652d1676b40891ec5d3f7c3ef4ae0fe37e74c3aee2ecda7912437e6", 
"d3e4bbbef77828ba171386e9b13aee059e1f20f466158b8c3e88ad75e7318b71", 
"d4701b30805dc2308cf42db79be1bd3497073d8e4ab9dc282bf6fe011eeecbb3", 
"d5ed71e7255587c4998d5f939d7855f8ed93544dbade7fb51745a603cdde632f", 
"d5fc0599fa9f449f8823e558c6e92f4b724f1f5a7b7f190e3ae71f34d7f0d648", 
"d9145c96355991032768f31b44e85e88569d6d93ed5e78b0301acc3674e391b1", 
"daa86daccb5a9d9a68c7868b58e2d68133bb75be7b4d7014533908e9d75dc3b0", 
"dc14e84d2ef14b79553e5e4f27edcae2a01a8ea3f79ca30224161dca7ad66fa9", 
"dc74fe83312f9e55bec1659be9ba8089846769e9f2450553bcda57d89b1d2a25", 
"dce43a57e2e950f9b2ac7003257c65070d90e3bfba57309e5ec7deea1e9e52c3", 
"def2b97b17756abb3ebe4dbd4abf5c04a1bfd826f9d9f9a284f3908f2b13ae7a", 
"e3fdd3d66f6388882530707da6f5b7dc35b94b80a3da59b60e3ebd5245edd456", 
"e43557478bc640338c6adc975d4ebf2c3e0c334f9243d99f13e4a095c9c4738a", 
"e5eedee2cd5a243b002b6e349a2a54820042228c0073fa98d68507fee29f5173", 
"e65a4b4cfc98a76d983eafd6e018db9a18e345a8b463e7e06419f29c0a62b905", 
"eb177ae9d7eb667f0b5660061511d57ffa51174fb751a7db2e82c0027274b689", 
"eccfd28fcb141bcd626ea09117ce0f0cfcbe69f74a6058a8c40f97f52aa7b7b7", 
"ed1dfca663bbda5153914ce9638d8c526be3d73c5d7c02de6062556140dca43b", 
"ed6bf56b27d6a9a132b5dab51bf691b9002ad455bead2703eab43ddd8d7094d9", 
"ef45400aa5b2702bbe4924783dbd3c1c7ae03fdd060f9ae0ba9f60629ce30691", 
"ef81ab6acd97c2872c2efbb64dc243623b59e3508e50d560ced942a9e11c2e2b", 
"f0994d4bbd8610ab678d095f82c1800e07bc9557076229fda7a3c7f6b9f9a953", 
"f1d706c1783c410b924b293f891f4d9d0ad385d7f8c2593ce1e61382068b7168", 
"f22b47ced72d99d45d09a1041f30b05b2763856cc3e4e729d0ff74b5b1ef33b6", 
"f5d309db1e4e9ea2d7866b2c5c2d22749e191b4ef5eea60a455f35484915edc3", 
"f74c05a72214feba49e9650130585e7bce5403325fbc8696b1b070525d8cde44", 
"f7f0294590261ba66c07751ea6cbde36d1f1cfadb701ab8cec081909bc47d152", 
"fbb936488ba2109e24f1e2f30b46ad702c3e1a2e90bb1c0e038697bab26516ef", 
"fbd55891773c0f0b597af9f0aafd4ac7da981638dad892362107f8afa2b2791a", 
"fc4272c6ebda86fb799d94af67ad6763072b109b71ffd6e005bfbca7d8e435d4", 
"fd98a0c5fb06a70721cc2ae48b160cc0b4cd7f12c1a3ba56cc14b6597ef41028", 
"feccc6925f6a65075851efc07d9aeee9486f1e9ad18669e9faadd3b9565dd2d3"
)
ppoo_clus_pre_pam_om4_q_clasificaciones_sin_asw_neg<-
df_filled2[, c("run", "glosa_pueblo_originario")] |>
  left_join(
    ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens[, c("run", "clus_pam_om4", "ci_cya_conadi", "ppoo_minsal_y_rsh_2010")], 
    by = "run"
  ) |>
  mutate(glosa_pueblo_originario_rec = if_else(
 glosa_pueblo_originario == "NINGUNO" & (ci_cya_conadi ==1 | ppoo_minsal_y_rsh_2010==1), "DESCONOCIDO", glosa_pueblo_originario
  )) |>
  filter(!run %in% neg_sil_width) |> 
  group_by(run, clus_pam_om4) |>
  summarise(
    tiene_otro_po = any(grepl("AYMARA|COLLA|DIAGUITA|KAWÉSQAR|RAPA NUI|YAGÁN|OTRO", glosa_pueblo_originario_rec)),
    tiene_mapuche = any(grepl("MAPUCHE", glosa_pueblo_originario_rec)),
    tiene_ninguno = any(glosa_pueblo_originario_rec == "NINGUNO"),
    tiene_desconocido = any(glosa_pueblo_originario_rec == "DESCONOCIDO"),
    .groups = "drop"
  ) |>
  mutate(clas_por_run = case_when(
    tiene_mapuche ~ "Mapuche",
    !tiene_mapuche & tiene_otro_po ~ "Otros reportados (no mapuche)",
    tiene_ninguno & !tiene_otro_po & !tiene_mapuche ~ "Ninguno puro",
    tiene_desconocido & !tiene_ninguno & !tiene_otro_po & !tiene_mapuche ~ "Desconocido puro", T~NA_character_
  )) |>
  janitor::tabyl(clas_por_run, clus_pam_om4, show_na = T)

janitor::adorn_percentages(ppoo_clus_pre_pam_om4_q_clasificaciones_sin_asw_neg, "row") |> 
  mutate_if(is.numeric, ~round(.*100, 1)) |> 
  knitr::kable("markdown", caption="Otra forma de clasificación PPOO con reporte vs. conglomerados (por fila) (excluye ASW neg)")

cat("Fisher test (menos los -ASWs)\n")
janitor::fisher.test(ppoo_clus_pre_pam_om4_q_clasificaciones_sin_asw_neg, simulate.p.value=T, B=1e5)
#p-value = 0.00258

cat("No vale la pena repetir el post-hoc, es muy similar todo (lo hice)")
#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L
#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L
cat("el primer evento ver qué reportaron a MINSAL en PPOO, pero la detección de desconocidos sigue siendo desde 2005")

ppoo_clus_pre_pam_om4_q_clasificaciones2<-
ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens[, c("run", "clus_pam_om4", "ci_cya_conadi", "ppoo_minsal_y_rsh_2010")] |>
  left_join(
    df_filled2[, c("run", "glosa_pueblo_originario")], 
    by = "run",
    multiple ="first"
  ) |>
  mutate(glosa_pueblo_originario_rec = if_else(
 glosa_pueblo_originario == "NINGUNO" & (ci_cya_conadi ==1 | ppoo_minsal_y_rsh_2010==1), "DESCONOCIDO", glosa_pueblo_originario
  )) |>
  #filter(!run %in% neg_sil_width) |> 
  group_by(run, clus_pam_om4) |>
  summarise(
    tiene_otro_po = any(grepl("AYMARA|COLLA|DIAGUITA|KAWÉSQAR|RAPA NUI|YAGÁN|OTRO", glosa_pueblo_originario_rec)),
    tiene_mapuche = any(grepl("MAPUCHE", glosa_pueblo_originario_rec)),
    tiene_ninguno = any(glosa_pueblo_originario_rec == "NINGUNO"),
    tiene_desconocido = any(glosa_pueblo_originario_rec == "DESCONOCIDO"),
    .groups = "drop"
  ) |>
  mutate(clas_por_run = case_when(
    tiene_mapuche ~ "Mapuche",
    !tiene_mapuche & tiene_otro_po ~ "Otros reportados (no mapuche)",
    tiene_ninguno & !tiene_otro_po & !tiene_mapuche ~ "Ninguno puro",
    tiene_desconocido & !tiene_ninguno & !tiene_otro_po & !tiene_mapuche ~ "Desconocido puro", T~NA_character_
  )) |>
  janitor::tabyl(clas_por_run, clus_pam_om4, show_na = T)

ppoo_clus_pre_pam_om4_q_clasificaciones2|>
      janitor::adorn_percentages("col")     |>  # convierte a proporciones por columna
      janitor::adorn_pct_formatting(digits = 1) |>  # “12.3%”
      janitor::adorn_ns(position = "front")  |>  # “12 (34.5%)”
   mutate(clas_por_run= factor(clas_por_run, levels= c("Ninguno puro", "Desconocido puro", "Otros reportados (no mapuche)", "Mapuche"))) |> 
  arrange(clas_por_run) |>
    (\(df) {
      if (interactive()) {df|> rio::export("clipboard")}
      knitr::kable(df, "markdown", caption="Otra forma de clasificación PPOO con reporte vs. conglomerados (por columna)")
    })()


janitor::fisher.test(ppoo_clus_pre_pam_om4_q_clasificaciones2, simulate.p.value=T, B=1e5)
#p-value = 0.0101

chisq.posthoc.test(ppoo_clus_pre_pam_om4_q_clasificaciones2[,2:5],simulate.p.value=T, B=1e5)|> 
  (\(df) { dplyr::mutate_at(df, 3:ncol(df), ~ round(as.numeric(gsub("\\*", "", .)), 3))
  })()|>
  group_by(Dimension)|>
  (\(df) { summarise(df, across(2:(ncol(df)-1), ~ paste0(first(sprintf("%1.2f", .)), " (p=", last(sprintf("%1.3f", .)), ")")))
  })()|>
  (\(df) { dplyr::mutate_at(df, 2:length(names(df)), ~ gsub("p\\=0.000)", "p<0.001)", .))
  })()|>
  mutate(Dimension= ppoo_clus_pre_pam_om4_q_clasificaciones[,1]) |> 
  mutate(Dimension= factor(Dimension, levels= c("Ninguno puro", "Desconocido puro", "Otros reportados (no mapuche)", "Mapuche"))) |> 
  arrange(Dimension) |>
  mutate(Dimension= as.character(Dimension)) |> 
  knitr::kable("markdown", caption = "Comparación post-hoc, conglomerado-PPOO autorreporte")

  cat("Tampoco resulta significativo en https://adaptivedesignstrial.shinyapps.io/posthoc/\n")
print("Eso si resulta interesante que los 25 usuarios desconcidos puro son 0.02 aunque en conjunto no hay bonferroni ni nada, pero son mas grandes; también es más grande Mapuche")

#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L
#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L
cat("Descartando siluetas negativas, para el primer evento ver qué reportaron a MINSAL en PPOO")
ppoo_clus_pre_pam_om4_q_clasificaciones_sin_asw_neg2<-
ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens[, c("run", "clus_pam_om4", "ci_cya_conadi", "ppoo_minsal_y_rsh_2010")] |>
  left_join(
    df_filled2[, c("run", "glosa_pueblo_originario")], 
    by = "run",
    multiple ="first"
  ) |>
  mutate(glosa_pueblo_originario_rec = if_else(
 glosa_pueblo_originario == "NINGUNO" & (ci_cya_conadi ==1 | ppoo_minsal_y_rsh_2010==1), "DESCONOCIDO", glosa_pueblo_originario
  )) |>
  filter(!run %in% neg_sil_width) |> 
  group_by(run, clus_pam_om4) |>
  summarise(
    tiene_otro_po = any(grepl("AYMARA|COLLA|DIAGUITA|KAWÉSQAR|RAPA NUI|YAGÁN|OTRO", glosa_pueblo_originario_rec)),
    tiene_mapuche = any(grepl("MAPUCHE", glosa_pueblo_originario_rec)),
    tiene_ninguno = any(glosa_pueblo_originario_rec == "NINGUNO"),
    tiene_desconocido = any(glosa_pueblo_originario_rec == "DESCONOCIDO"),
    .groups = "drop"
  ) |>
  mutate(clas_por_run = case_when(
    tiene_mapuche ~ "Mapuche",
    !tiene_mapuche & tiene_otro_po ~ "Otros reportados (no mapuche)",
    tiene_ninguno & !tiene_otro_po & !tiene_mapuche ~ "Ninguno puro",
    tiene_desconocido & !tiene_ninguno & !tiene_otro_po & !tiene_mapuche ~ "Desconocido puro", T~NA_character_
  )) |>
  janitor::tabyl(clas_por_run, clus_pam_om4, show_na = T)

janitor::adorn_percentages(ppoo_clus_pre_pam_om4_q_clasificaciones_sin_asw_neg2, "row") |> 
  mutate_if(is.numeric, ~round(.*100, 1)) |> 
  knitr::kable("markdown", caption="Otra forma de clasificación PPOO con reporte vs. conglomerados (por fila) (excluye ASW neg)")

cat("Fisher test (menos los -ASWs), nueva clasificación (primer evento reportado)\n")
janitor::fisher.test(ppoo_clus_pre_pam_om4_q_clasificaciones_sin_asw_neg2, simulate.p.value=T, B=1e5)
#p-value = 0.00266

cat("No vale la pena repetir el post-hoc, es muy similar todo (lo hice)")
Sólo RAPA NUI y MAPUCHE (ver por RUN, al menos una observación que se identifique RAPA NUI o MAPUCHE)

    Pearson's Chi-squared test

data:  (ppoo_clus_pre_pam_om4_q_act)
X-squared = 6.2657, df = 3, p-value = 0.09938

Sólo RAPA NUI (ver por RUN, al menos una observación que se identifique RAPA NUI)

    Fisher's Exact Test for Count Data

data:  (ppoo_clus_pre_pam_om4_q_rapa)
p-value = 0.009065
alternative hypothesis: two.sided

son 12 casos!
______________________
ESTE ES EL REPORTE QUE ESTÁ PUBLICAODO AL 2025-05-16 EN EL ARTICULO
______________________
Porcentajes por columna, conglomerado vs. PPOO
clas_por_run n percent
Ninguno puro 5310 80.1
Desconocido puro 1029 15.5
Otros reportados (no mapuche) 112 1.7
Mapuche 175 2.6
Porcentajes por columna, conglomerado vs. PPOO
clas_por_run 6623, Un trimestre, TSM(4) 6612, Un trimestre, TUS(3) 6522, Un semestre TSM(1) 6574, Comorbilidad un trimestre(2)
Ninguno puro 80.2 77.7 82.0 83.4
Desconocido puro 15.5 18.0 12.5 13.1
Otros reportados (no mapuche) 1.8 0.5 2.5 0.9
Mapuche 2.5 3.7 3.0 2.6

    Fisher's Exact Test for Count Data with simulated p-value (based on
    1e+05 replicates)

data:  ppoo_clus_pre_pam_om4_q_clasificaciones
p-value = 0.0102
alternative hypothesis: two.sided
Comparación post-hoc, conglomerado-PPOO autorreporte
Dimension 6623, Un trimestre, TSM(4) 6612, Un trimestre, TUS(3) 6522, Un semestre TSM(1) 6574, Comorbilidad un trimestre(2)
Ninguno puro 0.25 (p=1.000) -1.75 (p=1.000) 0.94 (p=1.000) 1.26 (p=1.000)
Desconocido puro -0.08 (p=1.000) 1.98 (p=0.757) -1.71 (p=1.000) -1.03 (p=1.000)
Otros reportados (no mapuche) 1.71 (p=1.000) -2.61 (p=0.145) 1.30 (p=1.000) -0.98 (p=1.000)
Mapuche -1.81 (p=1.000) 1.98 (p=0.762) 0.47 (p=1.000) -0.02 (p=1.000)
Tampoco resulta significativo en https://adaptivedesignstrial.shinyapps.io/posthoc/
______________________
______________________
Otra forma de clasificación PPOO con reporte vs. conglomerados (por fila) (excluye ASW neg)
clas_por_run 6623, Un trimestre, TSM(4) 6612, Un trimestre, TUS(3) 6522, Un semestre TSM(1) 6574, Comorbilidad un trimestre(2)
Desconocido puro 81.0 13.4 2.6 3.0
Mapuche 76.3 16.6 3.6 3.6
Ninguno puro 81.1 11.2 4.0 3.7
Otros reportados (no mapuche) 87.3 3.6 7.3 1.8
Fisher test (menos los -ASWs)

    Fisher's Exact Test for Count Data with simulated p-value (based on
    1e+05 replicates)

data:  ppoo_clus_pre_pam_om4_q_clasificaciones_sin_asw_neg
p-value = 0.00237
alternative hypothesis: two.sided

No vale la pena repetir el post-hoc, es muy similar todo (lo hice)el primer evento ver qué reportaron a MINSAL en PPOO, pero la detección de desconocidos sigue siendo desde 2005
Otra forma de clasificación PPOO con reporte vs. conglomerados (por columna)
clas_por_run 6623, Un trimestre, TSM(4) 6612, Un trimestre, TUS(3) 6522, Un semestre TSM(1) 6574, Comorbilidad un trimestre(2)
Ninguno puro 4,209 (80.2%) 583 (77.7%) 327 (82.0%) 191 (83.4%)
Desconocido puro 866 (16.5%) 139 (18.5%) 55 (13.8%) 33 (14.4%)
Otros reportados (no mapuche) 67 (1.3%) 3 (0.4%) 10 (2.5%) 2 (0.9%)
Mapuche 106 (2.0%) 25 (3.3%) 7 (1.8%) 3 (1.3%)

    Fisher's Exact Test for Count Data with simulated p-value (based on
    1e+05 replicates)

data:  ppoo_clus_pre_pam_om4_q_clasificaciones2
p-value = 0.01382
alternative hypothesis: two.sided
Comparación post-hoc, conglomerado-PPOO autorreporte
Dimension 6623, Un trimestre, TSM(4) 6612, Un trimestre, TUS(3) 6522, Un semestre TSM(1) 6574, Comorbilidad un trimestre(2)
Ninguno puro 0.25 (p=1.000) -1.75 (p=1.000) 0.94 (p=1.000) 1.26 (p=1.000)
Desconocido puro 0.02 (p=1.000) 1.60 (p=1.000) -1.50 (p=1.000) -0.86 (p=1.000)
Otros reportados (no mapuche) 0.56 (p=1.000) -2.20 (p=0.441) 2.37 (p=0.289) -0.51 (p=1.000)
Mapuche -1.19 (p=1.000) 2.43 (p=0.242) -0.53 (p=1.000) -0.87 (p=1.000)
Tampoco resulta significativo en https://adaptivedesignstrial.shinyapps.io/posthoc/
[1] "Eso si resulta interesante que los 25 usuarios desconcidos puro son 0.02 aunque en conjunto no hay bonferroni ni nada, pero son mas grandes; también es más grande Mapuche"
Descartando siluetas negativas, para el primer evento ver qué reportaron a MINSAL en PPOO
Otra forma de clasificación PPOO con reporte vs. conglomerados (por fila) (excluye ASW neg)
clas_por_run 6623, Un trimestre, TSM(4) 6612, Un trimestre, TUS(3) 6522, Un semestre TSM(1) 6574, Comorbilidad un trimestre(2)
Desconocido puro 81.2 13.0 2.7 3.1
Mapuche 77.4 18.2 2.2 2.2
Ninguno puro 81.1 11.2 4.0 3.7
Otros reportados (no mapuche) 83.8 3.8 10.0 2.5
Fisher test (menos los -ASWs), nueva clasificación (primer evento reportado)

    Fisher's Exact Test for Count Data with simulated p-value (based on
    1e+05 replicates)

data:  ppoo_clus_pre_pam_om4_q_clasificaciones_sin_asw_neg2
p-value = 0.00249
alternative hypothesis: two.sided

No vale la pena repetir el post-hoc, es muy similar todo (lo hice)

Tiempo que demora esta sección: 0 minutos

Código
cat("(__________________________________________________________________)\n")
reshape2::melt(ppoo_clus_pre_pam_om4_q, id.vars = "glosa_pueblo_originario_rec") |> 
  dplyr::mutate(glosa_pueblo_originario_rec= 
    dplyr::recode(glosa_pueblo_originario_rec, 
      "OTRO (ESPECIFICAR)"= "OTRO(n=86)", #"OTRO(n=77)", 
      "RAPA NUI (PASCUENSE)"= "RAPA NUI(n=37)", #"RAPA NUI(n=34)", 
      "YAGÁN (YÁMANA)"= "YAGÁN(n=2)",#"YAGÁN(n=2)",
      "AYMARA"= "AYMARA(n=15)",#"AYMARA(n=13)",
      "COLLA"= "COLLA(n=6)",#"COLLA(n=6)",
      "DIAGUITA"= "DIAGUITA(n=3)",#"DIAGUITA(n=3)",
      "KAWÉSQAR"= "KAWÉSQAR(n=4)",#"KAWÉSQAR(n=4)",
      "MAPUCHE"= "MAPUCHE(n=299)",#"MAPUCHE(n=255)",
      "DESCONOCIDO"= ".DESCONOCIDO(n=2.353)",#".DESCONOCIDO(n=1.985)",
      "NINGUNO"=".NINGUNO(n=10.425)"#".NINGUNO(n=9.156)"
      )) |> 
ggplot(aes(x = glosa_pueblo_originario_rec, y = value, fill = variable)) + 
  geom_bar(stat = "identity", position = "fill") + 
  scale_fill_manual(values = c("#D2B48C", "#E27A5B", "#708090", "#6B8E23")) +
  labs(title = NULL,
       x = "Grupo Étnico",
       y = "Proporción de reportes",
       fill = "Grupos") +  # Cambia el título de la leyenda a "Grupos"
  theme_minimal() +
  theme(
    axis.text.y = element_text(size = 12),           # Tamaño de las etiquetas de los grupos étnicos
    axis.text.x = element_text(size = 12),           # Tamaño de las etiquetas del eje X
    axis.title.x = element_text(size = 14),          # Tamaño del título del eje X
    axis.title.y = element_text(size = 14),          # Tamaño del título del eje Y
    plot.title = NULL,  # Tamaño y estilo del título del gráfico
    legend.title = element_text(size = 14, margin = margin(b = -.1)),          # Tamaño del título de la leyenda
    legend.spacing.y = unit(1.5, "lines"),
    legend.box.spacing = unit(0.5, "lines"),      # Controla el espacio entre la leyenda y el gráfico
    legend.margin = margin(5, 5, 5, 5),  
    legend.key.height = unit(1, "cm"),  
    legend.text = element_text(size = 12)            # Tamaño del texto de la leyenda
    ) + 
  coord_flip()  # Hacer el gráfico horizontal
ggsave("_figs/grafico_ancho_achatado_pam_om4_q_25.png", width = 10, height = 5, dpi=1000)


ppoo_clus_pre_pam_om4_q_rapanui<-
  df_filled2[,c("run","glosa_pueblo_originario")] |> 
  dplyr::left_join(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens[,c("run", "clus_pam_om4","factor_inclusivo_real_hist_mas_autperc")], by="run", multiple="first") |> 
  dplyr::mutate(glosa_pueblo_originario_rec= dplyr::case_when(glosa_pueblo_originario=="NINGUNO" & factor_inclusivo_real_hist_mas_autperc!="00"~ "DESCONOCIDO", glosa_pueblo_originario=="NINGUNO"~"NINGUNO", glosa_pueblo_originario=="RAPA NUI (PASCUENSE)"~"RAPA NUI", T~"RESTO")) |> 
  janitor::tabyl(glosa_pueblo_originario_rec, clus_pam_om4) |> 
  janitor::adorn_percentages("row")

cat("\norigen, en caso que sospechemos de los patrones de hospitalización observados para RAPA NUI \n")
df_filled2[,c("run","glosa_pueblo_originario")] |> 
    dplyr::left_join(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens[,c("run", "clus_pam_om4","factor_inclusivo_real_hist_mas_autperc", "codigo_region_rec_base")], by="run", multiple="first")|> 
    dplyr::mutate(glosa_pueblo_originario_rec= dplyr::case_when(glosa_pueblo_originario=="NINGUNO" & factor_inclusivo_real_hist_mas_autperc!="00"~ "DESCONOCIDO", glosa_pueblo_originario=="NINGUNO"~"NINGUNO", glosa_pueblo_originario=="RAPA NUI (PASCUENSE)"~"RN", T~"RESTO")) |> 
    dplyr::filter(glosa_pueblo_originario_rec=="RN") |> janitor::tabyl(codigo_region_rec_base)
(__________________________________________________________________)

origen, en caso que sospechemos de los patrones de hospitalización observados para RAPA NUI 
 codigo_region_rec_base  n   percent
                     RM 22 0.5945946
                   noRM 15 0.4054054
Eventos hospitalarios y reportes de pertenencia a PPOO MINSAL, por conglomerados

Eventos hospitalarios y reportes de pertenencia a PPOO MINSAL, por conglomerados

Tiempo que demora esta sección: 0 minutos

1.1.1. Trayectorias

Vemos los gráficos de las trayectorias

Código
categories_pam_om4_q<-attr(States_Wide.seq_quarter_t_prim_adm_cens, "labels")
new_labels <- categories_pam_om4_q
new_labels[which(categories_pam_om4_q == "Otras causas")] <- "Otras\ncausas"
#new_labels[which(categories == "Consumo\nde sustancias")] <- "Consumo de\nsustancias"

# Creamos un vector con las columnas llenando con NA si faltan valores
sil_pam_om_clus4_q <- wcSilhouetteObs(as.dist(dist_quarter_om), 
        pamRange_quarter_om$clustering$cluster4, measure="ASW")


seq_plot_pam_om4_q <- ggseqiplot(States_Wide.seq_quarter_t_prim_adm_cens, 
                                 group= ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$clus_pam_om4,
                                 facet_ncol=2, facet_nrow=2, sortv=sil_pam_om_clus4_q) +
  theme(legend.position = "none")+
  labs(x="Trimestres", y="# IDs de usuarios")+
  #guides(fill = guide_legend(nrow = 1))+
  theme(
    panel.spacing = unit(0.1, "lines"),  # Reduce el espaciado entre los paneles
    axis.text.y = element_text(size = 15),           # Tamaño de las etiquetas de los grupos étnicos
    axis.text.x = element_text(size = 15),           # Tamaño de las etiquetas del eje X
    axis.title.x = element_text(size = 15),          # Tamaño del título del eje X
    axis.title.y = element_text(size = 15, margin = margin(r = -10)),#,margin = margin(l = -10)),
    strip.text = element_text(size = 11, margin = margin(b =-15)),
    legend.text = element_text(size = 15),
    legend.spacing.x = unit(0.1, 'cm'),  # Alinea el título de la leyenda hacia la izquierda
    legend.box.margin = margin(t = 0, r = 0, b = 0, l = -50),
    legend.position = "bottom", 
    legend.justification = "left",
    panel.spacing.y = unit(0.5, "lines"),
    strip.placement = "outside",   # Para colocar las tiras fuera de los ejes
    strip.background = element_blank() # Elimina el fondo para que parezca más espacioso
    #legend.key.size = unit(1.5, "lines"),        # Aumenta el tamaño de los símbolos en la leyenda
  )+
  guides(fill = guide_legend(nrow = 1)) +
  scale_fill_manual(labels = new_labels, values=c("#E2725B", "#556B2F", "#D2B48C",#"#8B4513",
                                                  "#FFFFFF","#808080","#000000"))+
  scale_color_manual(labels = new_labels, values=c("#E2725B", "#556B2F", "#D2B48C",#"#8B4513",
                                                   "#FFFFFF","#808080","#000000"))
seq_plot_pam_om4_q 

ggsave(filename="_figs/clusters_pam_om4_q_mod_25.png", seq_plot_pam_om4_q,  width = 9.5, height = 5.5, dpi=1000)

#:#:#:#:#:#:#:#:#:#:#:

ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$clus_pam_om4_eng <- ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$clus_pam_om4

levels(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$clus_pam_om4_eng) <-   c("1.First quarter, MH(6623)", "2.First quarter, SUD(6612)", "3.First semester, MH(6522)", "4.First quarter, comorbidity(6574)")

new_labels_eng <- c("Substance\nuse disorder",
                    "Comorbidity",
                    "Mental health\ndisorder",
                    "Not in\n hospital",
                    "Other\ncauses",
                    "Censored")

# Plot with translated labels and Times New Roman font
seq_plot_pam_om4_q_eng <-
  ggseqiplot(States_Wide.seq_quarter_t_prim_adm_cens,
    group = ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$clus_pam_om4_eng,
    facet_ncol = 2, facet_nrow = 2, sortv = sil_pam_om_clus4_q) +
  labs(x = "Quarters Since First MH/SUD Hospitalization", y = "Patient index number") +
  theme(
    text = element_text(family = "Times"),
    panel.spacing = unit(0.1, "lines"),
    axis.text.y = element_text(size = 15),
    axis.text.x = element_text(size = 15),
    axis.title.x = element_text(size = 15),
    axis.title.y = element_text(size = 15, margin = margin(r = -8)),
    strip.text = element_text(size = 15, margin = margin(b = -15)),
    legend.text = element_text(size = 15),
    legend.spacing.x = unit(0.1, 'cm'),
    legend.box.margin = margin(t = 0, r = 0, b = 0, l = -50),
    legend.position = "bottom",
    legend.justification = "left",
    panel.spacing.y = unit(0.5, "lines"),
    strip.placement = "outside",
    strip.background = element_blank()
  ) +
  guides(fill = guide_legend(nrow = 1)) +
  scale_fill_manual(labels = new_labels_eng, values = c("#E2725B", "#556B2F", "#D2B48C", "#FFFFFF", "#808080", "#000000")) +
  scale_color_manual(labels = new_labels_eng, values = c("#E2725B", "#556B2F", "#D2B48C", "#FFFFFF", "#808080", "#000000"))

ggsave(filename="_figs/clusters_pam_om4_q_mod_eng_25.png", seq_plot_pam_om4_q_eng,  width = 9.5, height = 5.5, dpi=1000)
Trayectorias de hospitalización, orden de sujetos según el primer estado observado y su duración, representando a cada individuo como una línea en el gráfico (observaciones ordenadas de acuerdo a ASW)

Trayectorias de hospitalización, orden de sujetos según el primer estado observado y su duración, representando a cada individuo como una línea en el gráfico (observaciones ordenadas de acuerdo a ASW)

Tiempo que demora esta sección: 0.2 minutos

Código
seq_plot2_pam_om4_q <- ggseqdplot(States_Wide.seq_quarter_t_prim_adm_cens, 
                                 group= ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$clus_pam_om4,
                                 facet_ncol=2, facet_nrow=2) +
  theme(legend.position = "none")+  # Colocar la leyenda abajo
  labs(x="Trimestres", y="Frecuencia relativa de estados")+
  theme(
    panel.spacing = unit(0.1, "lines"),
    axis.text.y = element_text(size = 15),           # Tamaño de las etiquetas de los grupos étnicos
    axis.text.x = element_text(size = 15),           # Tamaño de las etiquetas del eje X
    axis.title.x = element_text(size = 15),          # Tamaño del título del eje X
    axis.title.y = element_text(size = 15, margin = margin(r = -5)),
    strip.text = element_text(size = 15),
    panel.spacing.y = unit(0.5, "lines"),
    strip.placement = "outside",   # Para colocar las tiras fuera de los ejes
    strip.background = element_blank() # Elimina el fondo para que parezca más espacioso
    #legend.key.size = unit(1.5, "lines"),        # Aumenta el tamaño de los símbolos en la leyenda    
  )  # Colocar la leyenda abajo
seq_plot2_pam_om4_q
ggsave("_figs/clusterspam_om42_q_mod_25.png",seq_plot2_pam_om4_q, width = 8.5, height = 5.5, dpi=1000)


table_data_pam_om4_q <- sprintf("%1.2f",pamRange_quarter_om$stats[3,])
table_data_pam_om4_q <-as.data.frame(t(table_data_pam_om4_q))
colnames(table_data_pam_om4_q)<-attr(pamRange_quarter_om$stats, "name")
table_data_pam_om4_q |> knitr::kable()
PBC HG HGSD ASW ASWw CH R2 CHsq R2sq HC
0.49 0.66 0.65 0.58 0.59 948.53 0.30 1312.64 0.37 0.20

Trayectorias de hospitalización, frecuencia relativa de estados en un gráfico de barras apiladas por trimestre.

Trayectorias de hospitalización, frecuencia relativa de estados en un gráfico de barras apiladas por trimestre.

Trayectorias de hospitalización, frecuencia relativa de estados en un gráfico de barras apiladas por trimestre.

Tiempo que demora esta sección: 0 minutos

Código
new_labels_eng2 <- c("Censored",
                    "Other\ncauses",
                    "Not in\n hospital",
                    "Mental health\ndisorder",
                    "Comorbidity",
                    "Substance\nuse disorder"                    
                    )
seq_plot_pam_om4_q_eng <-
  ggseqdplot(States_Wide.seq_quarter_t_prim_adm_cens,
    group = ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$clus_pam_om4,
    facet_ncol = 2, facet_nrow = 2) +
  labs(x = "Quarters Since First MH/SUD Hospitalization", y = "Proportion") +
  theme(
    text = element_text(family = "Times"),
    panel.spacing = unit(0.1, "lines"),
    axis.text.y = element_text(size = 15),
    axis.text.x = element_text(size = 15),
    axis.title.x = element_text(size = 15),
    axis.title.y = element_text(size = 15, margin = margin(r = -8)),
    strip.text = element_text(size = 15, margin = margin(b = -15)),
    legend.text = element_text(size = 15),
    legend.spacing.x = unit(0.1, 'cm'),
    legend.box.margin = margin(t = 0, r = 0, b = 0, l = -50),
    legend.position = "bottom",
    legend.justification = "left",
    panel.spacing.y = unit(0.5, "lines"),
    strip.placement = "outside",
    strip.background = element_blank()
  ) +
  guides(fill = guide_legend(nrow = 1)) +
  scale_fill_manual(labels = new_labels_eng2, values = c("#000000", "#808080", "#FFFFFF", "#D2B48C", "#556B2F", "#E2725B"))+
  scale_color_manual(labels = new_labels_eng2, values = c("#000000", "#808080", "#FFFFFF", "#D2B48C", "#556B2F", "#E2725B"))

ggsave(filename="_figs/clusters_pam_om4_q_mod_eng_25_2.png", seq_plot_pam_om4_q_eng,  width = 9.5, height = 5.5, dpi=1000)

Tiempo que demora esta sección: 0 minutos

De este modo, presenta el cambio agregado en la distribución de estados a lo largo del tiempo, sin considerar las secuencias individuales.

Código
cat("Definimos las observaciones que tienen siluetas negativas")
sil_neg_pam_om_clus4_q <- which(sil_pam_om_clus4_q<0)

cat("A qué conglomerados pertenecen?")
table(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens[sil_neg_pam_om_clus4_q, "clus_pam_om4"])

ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$rn<- 1:nrow(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens)
Definimos las observaciones que tienen siluetas negativasA qué conglomerados pertenecen?clus_pam_om4
        6623, Un trimestre, TSM(4)         6612, Un trimestre, TUS(3) 
                                 2                                  0 
          6522, Un semestre TSM(1) 6574, Comorbilidad un trimestre(2) 
                               151                                  0 

Tiempo que demora esta sección: 0 minutos

1.1.2.Exploración transiciones

1.1.2.a Transiciones- RM y no RM

Tasas de transición no RM a RM y viceversa

Código
invisible("Tasas de transición no RM a RM y viceversa")

trim_tasa_pam_om4_q_cens_cnt<-  
  seqcount_t(States_Wide.seq_quarter_t_prim_adm_RM_cens, 
             group=ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$clus_pam_om4) |> 
  dplyr::filter(count>0) |> 
  dplyr::mutate(trans = paste0(from,"_", to)) |> 
  dplyr::mutate(across(c("from","to"),~  gsub("\\[->\\s*|\\s*->\\s*\\]|\\[|\\]", "", .))) 
trim_tasa_pam_om4_q_cens_rate<-  
  seqtrate_t(States_Wide.seq_quarter_t_prim_adm_RM_cens, 
             group=ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$clus_pam_om4) |> 
  dplyr::filter(rate>0) |> 
  dplyr::mutate(trans = paste0(from,"_", to)) |> 
  dplyr::mutate(across(c("from","to"),~  gsub("\\[->\\s*|\\s*->\\s*\\]|\\[|\\]", "", .)))

cat("Número de transiciones de RM a noRM y viceversa\n")


cat("Transiciones de noRM a RM\n")
trim_tasa_pam_om4_q_cens_cnt |> 
  filter(from=="noRM", to=="RM") |> 
    summarise(n=sum(count))

cat("Transiciones de RM a noRM\n")
trim_tasa_pam_om4_q_cens_cnt |> 
  filter(from=="RM", to=="noRM") |> 
    summarise(n=sum(count))

cat("Total de transiciones\n")
trim_tasa_pam_om4_q_cens_cnt |> 
    summarise(n=sum(count))

cat("Proporción de transiciones de noRM a RM y viceversa\n")
sum(trim_tasa_pam_om4_q_cens_cnt |> 
  filter(from=="noRM", to=="RM") |> 
    summarise(n=sum(count)),trim_tasa_pam_om4_q_cens_cnt |> 
  filter(from=="RM", to=="noRM") |> 
    summarise(n=sum(count)))/
trim_tasa_pam_om4_q_cens_cnt |> 
    summarise(n=sum(count))

Tiempo que demora esta sección: 0 minutos

Código
trim_tasa_pam_om4_q_cens_rate |>   
  dplyr::left_join(trim_tasa_pam_om4_q_cens_cnt, by=c("from"="from", "glosa_sexo"="glosa_sexo","to"="to")) |> 
  dplyr::rename("recuento"="count") |> 
  dplyr::filter(from %in% c("RM", "noRM")) |>  
  ggplot(aes(x = from, y = to, fill = rate, size=log(recuento+1))) +
  geom_tile() +
  coord_flip()+
  scale_fill_gradient(low = "white", high = "blue") + # Ajusta la escala de colores según tus preferencias
  labs(title = "Tasas de transición, Trimestre (s/censura)",
       x = "Desde",
       y = "Hacia",
       fill = "Rate") +
  theme_minimal() +
  facet_wrap(~glosa_sexo)+
  theme(axis.text.x = element_text(angle = 45, hjust = 1))+
  geom_text(aes(label = sprintf("%1.2f", rate), size =log(recuento+1)*.5), color = "black")

invisible("Hay muy pocos casos que se entrecruzan entre noRM y RM (fuera de la diagnonal)")
Porcentajes de transición no-RM y RM por cada cluster

Porcentajes de transición no-RM y RM por cada cluster

Tiempo que demora esta sección: 0 minutos

Hay muy pocos casos que se entrecruzan entre noRM y RM (fuera de la diagnonal)

1.1.2.b Transiciones
Código
trim_tasa2_pam_om4_q_cens_cnt<-  
   seqcount_t(States_Wide.seq_quarter_t_prim_adm_cens, 
             group=ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$clus_pam_om4) |> 
  dplyr::filter(count>0) |> 
  dplyr::mutate(trans = paste0(from,"_", to)) |> 
  dplyr::mutate(across(c("from","to"),~  gsub("\\[->\\s*|\\s*->\\s*\\]|\\[|\\]", "", .))) 
trim_tasa2_pam_om4_q_cens_rate<-  
  seqtrate_t(States_Wide.seq_quarter_t_prim_adm_cens, 
             group=ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$clus_pam_om4) |> 
  dplyr::filter(rate>0) |> 
  dplyr::mutate(trans = paste0(from,"_", to)) |> 
  dplyr::mutate(across(c("from","to"),~  gsub("\\[->\\s*|\\s*->\\s*\\]|\\[|\\]", "", .)))

Tiempo que demora esta sección: 0 minutos

Código
trim_tasa2_pam_om4_q_cens_rate |>   
  dplyr::left_join(trim_tasa2_pam_om4_q_cens_cnt, by=c("from"="from", "glosa_sexo"="glosa_sexo","to"="to")) |> 
  dplyr::rename("recuento"="count") |> 
  #dplyr::filter(from %in% c("RM", "noRM")) |>  
  ggplot(aes(x = from, y = to, fill = rate, size=log(recuento+1))) +
  geom_tile() +
  coord_flip()+
  scale_fill_gradient(low = "white", high = "blue") + # Ajusta la escala de colores según tus preferencias
  labs(title = "Tasas de transición, Trimestre (s/censura)",
       x = "Desde",
       y = "Hacia",
       fill = "Rate") +
  theme_minimal() +
  facet_wrap(~glosa_sexo)+
  theme(axis.text.x = element_text(angle = 45, hjust = 1))+
  geom_text(aes(label = sprintf("%1.2f", rate), size =log(recuento+1)*.5), color = "black")
Porcentajes de transición, transiciones posteriores, por cada cluster

Porcentajes de transición, transiciones posteriores, por cada cluster

Tiempo que demora esta sección: 0 minutos

1.1.2.c Tiempo promedio por cluster
Código
seq_mean_t(States_Wide.seq_quarter_t_prim_adm_cens, 
             group=ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$clus_pam_om4) |> 
  data.table::as.data.table(keep.rowname=T) |>
  dplyr::mutate(rn= gsub("\\d", "", rn)) |> 
  ggplot(aes(x=rn, fill= factor_inclusivo, y=Mean))+
  geom_bar(width = 1, stat = "identity") +
  theme_minimal() +
  facet_wrap(~factor_inclusivo)+
  labs(title = NULL,
       x = NULL,
       y = NULL) +
  scale_fill_manual(values = c("#70809090", "#6B8E2380", "#E27A5B","#D2B48C")) +
  coord_flip()+
  theme(#axis.text.x = element_blank(),
    #axis.text.y = element_blank(),
    panel.grid = element_blank()) +
#  scale_fill_brewer(palette = "Pastel1", labels=c("Sin\nautoidentificación\nni reconocimiento", "Autoidentificación\nsin reconocimiento", "Ambas")) +
  geom_text(aes(label = round(Mean,1)), 
            position = position_stack(vjust = 0.5), 
            size = 3.5, # Ajusta el tamaño de la fuente aquí
            color = "black", # Color del texto
            family = "sans", # Puedes cambiar la fuente si lo deseas
            background = element_rect(fill = "white", color = NA)) + # Fondo blanco
  theme(legend.title = element_blank())

invisible("No me aporta mucho")
Tiempo promedio en cada estado por estatus PPOO (Trimestral c/censura)

Tiempo promedio en cada estado por estatus PPOO (Trimestral c/censura)

Tiempo que demora esta sección: 0 minutos

Observamos que aquellos en el conglomerado que se encuentra un trimestre, la duración de los ingresos relacionados con trastornos de salud mental son en promedio más largos.

1.1.3. Comparación variables

1.1.3.a. Comparación covariables- PPOO
Código
ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$fac_incl_real_hist_autoperc25<-
  with(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, paste0(ci_cya_conadi, ppoo_minsal_y_rsh_2010))

ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens|>
  #dplyr::count(clus_pam_om4, factor_inclusivo_real_hist_mas_autperc)|>
  #2025-04-14: converted
  dplyr::count(clus_pam_om4, fac_incl_real_hist_autoperc25)|> 
  dplyr::group_by(clus_pam_om4)|>
  dplyr::mutate(n_prop = paste0(n, " (",scales::percent(n / sum(n), accuracy=.1),")"))|>
  dplyr::select(-n)|>
  tidyr::pivot_wider(names_from = clus_pam_om4, values_from = n_prop, values_fill = "0")|>
  dplyr::mutate(fac_incl_real_hist_autoperc25 = factor(fac_incl_real_hist_autoperc25, levels = c("11", "10", "01", "00"), labels= c("Hay reconocimeinto/se identifica", "Hay reconocimiento/no se identifica", "No hay reconocimiento/se identifica", "No hay reconocimiento/no se identifica")))|> 
  dplyr::arrange(fac_incl_real_hist_autoperc25)|>
  (\(df) {
  if (interactive()) {mutate(df, across(-fac_incl_real_hist_autoperc25, ~ gsub("%", "", gsub("\\.", ",", .))))|> rio::export("clipboard")}
  knitr::kable(df, caption="Porcentajes por fila, conglomerado vs. Pertenencia/identificación + Reconocimento CONADI PPOO")
  })()
Porcentajes por fila, conglomerado vs. Pertenencia/identificación + Reconocimento CONADI PPOO
fac_incl_real_hist_autoperc25 6623, Un trimestre, TSM(4) 6612, Un trimestre, TUS(3) 6522, Un semestre TSM(1) 6574, Comorbilidad un trimestre(2)
Hay reconocimeinto/se identifica 336 (6.4%) 59 (7.9%) 18 (4.5%) 12 (5.2%)
Hay reconocimiento/no se identifica 107 (2.0%) 16 (2.1%) 9 (2.3%) 5 (2.2%)
No hay reconocimiento/se identifica 596 (11.4%) 92 (12.3%) 45 (11.3%) 21 (9.2%)
No hay reconocimiento/no se identifica 4209 (80.2%) 583 (77.7%) 327 (82.0%) 191 (83.4%)

Tiempo que demora esta sección: 0 minutos

Vemos las categorías de clasificación de PPOO según autopercepción (en MINSAL y en RSH) y reconocimiento CONADI.

Código
chisq.test(table(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$fac_incl_real_hist_autoperc25,ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$clus_pam_om4))
# data:  table(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$factor_inclusivo_real_hist_mas_autperc,     ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$clus_pam_om4)
# X-squared = 7.8526, df = 9, p-value = 0.5491
# 
fisher.test(table(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$fac_incl_real_hist_autoperc25,ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$clus_pam_om4), simulate.p.value = T, B=1e5)
#p-value = 0.5482

chisq_cramerv(
with(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, table(fac_incl_real_hist_autoperc25 , clus_pam_om4))
)
# $chisq_statistic
# [1] "7.85"
# 
# $chisq_df
# df 
#  9 
# 
# $chisq_p_value
# [1] "0.5491"
# 
# $cramers_v
# [1] "0.02"
message("Descartando valores negativos en sil width")
chisq.test(
with(subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, !rn %in% sil_neg_pam_om_clus4_q), table(fac_incl_real_hist_autoperc25 , clus_pam_om4))
)
# X-squared = 8.2613, df = 6, p-value = 0.2196
fisher.test(
with(subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, !rn %in% sil_neg_pam_om_clus4_q), table(fac_incl_real_hist_autoperc25 , clus_pam_om4)), simulate.p.value = T, B=1e5
)
# p-value = 0.3417
# 

chisq.posthoc.test(with(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, table(fac_incl_real_hist_autoperc25 , clus_pam_om4)),simulate.p.value=T, B=1e5)|> 
  (\(df) { dplyr::mutate_at(df, 3:ncol(df), ~ round(as.numeric(gsub("\\*", "", .)), 3))
  })()|>
  group_by(Dimension)|>
  (\(df) { summarise(df, across(2:(ncol(df)-1), ~ paste0(first(sprintf("%1.2f", .)), " (p=", last(sprintf("%1.3f", .)), ")")))
  })()|>
  (\(df) { dplyr::mutate_at(df, 2:length(names(df)), ~ gsub("p\\=0.000)", "p<0.001)", .))
  })()|>
  mutate(Dimension= ppoo_clus_pre_pam_om4_q_clasificaciones[,1]) |> 
  knitr::kable("markdown", caption = "Comparación post-hoc, conglomerado-PPOO autorreporte")

    Pearson's Chi-squared test

data:  table(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$fac_incl_real_hist_autoperc25,     ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$clus_pam_om4)
X-squared = 7.8526, df = 9, p-value = 0.5491


    Fisher's Exact Test for Count Data with simulated p-value (based on
    1e+05 replicates)

data:  table(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$fac_incl_real_hist_autoperc25, ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$clus_pam_om4)
p-value = 0.5426
alternative hypothesis: two.sided

$chisq_statistic
[1] "7.85"

$chisq_df
df 
 9 

$chisq_p_value
[1] "0.5491"

$cramers_v
[1] "0.02"


    Pearson's Chi-squared test

data:  with(subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens,     !rn %in% sil_neg_pam_om_clus4_q), table(fac_incl_real_hist_autoperc25,     clus_pam_om4))
X-squared = 9.7767, df = 9, p-value = 0.3689


    Fisher's Exact Test for Count Data with simulated p-value (based on
    1e+05 replicates)

data:  with(subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, !rn %in% sil_neg_pam_om_clus4_q), table(fac_incl_real_hist_autoperc25, clus_pam_om4))
p-value = 0.3468
alternative hypothesis: two.sided
Comparación post-hoc, conglomerado-PPOO autorreporte
Dimension 6623, Un trimestre, TSM(4) 6612, Un trimestre, TUS(3) 6522, Un semestre TSM(1) 6574, Comorbilidad un trimestre(2)
Desconocido puro 0.25 (p=1.000) -1.75 (p=1.000) 0.94 (p=1.000) 1.26 (p=1.000)
Mapuche -0.11 (p=1.000) 0.81 (p=1.000) -0.07 (p=1.000) -1.07 (p=1.000)
Ninguno puro -0.32 (p=1.000) 0.13 (p=1.000) 0.27 (p=1.000) 0.12 (p=1.000)
Otros reportados (no mapuche) -0.08 (p=1.000) 1.72 (p=1.000) -1.60 (p=1.000) -0.74 (p=1.000)

Tiempo que demora esta sección: 0 minutos

Ahora lo hacemos con la versión binarizada

Código
ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$factor_inclusivo_real_hist_mas_autperc_bin<- ifelse(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$fac_incl_real_hist_autoperc25=="00",0,1)

ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens |> 
    dplyr::mutate(death_time_rec=ifelse(death_time==20,0,1)) |> 
    janitor::tabyl(factor_inclusivo_real_hist_mas_autperc_bin,clus_pam_om4) |>
    janitor::chisq.test()
#X-squared = 5.1024, df = 3, p-value = 0.1644
#

chisq_cramerv(
with(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, table(factor_inclusivo_real_hist_mas_autperc_bin, clus_pam_om4))
)
# $chisq_statistic
# [1] "5.10"
# 
# $chisq_df
# df 
#  3 
# 
# $chisq_p_value
# [1] "0.1644"
# 
# $cramers_v
# [1] "0.03"
message("Descartando valores negativos en sil width")
chisq.test(
with(subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, !rn %in% sil_neg_pam_om_clus4_q), table(factor_inclusivo_real_hist_mas_autperc_bin , clus_pam_om4))
)
#X-squared = 6.4466, df = 3, p-value = 0.09179

chisq_cramerv(
with(subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, !rn %in% sil_neg_pam_om_clus4_q), table(factor_inclusivo_real_hist_mas_autperc_bin, clus_pam_om4))
)
# $chisq_statistic
# [1] "6.45"
# 
# $chisq_df
# df 
#  3 
# 
# $chisq_p_value
# [1] "0.0918"
# 
# $cramers_v
# [1] "0.03"

    Pearson's Chi-squared test

data:  janitor::tabyl(dplyr::mutate(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens,     death_time_rec = ifelse(death_time == 20, 0, 1)), factor_inclusivo_real_hist_mas_autperc_bin,     clus_pam_om4)
X-squared = 5.1024, df = 3, p-value = 0.1644

$chisq_statistic
[1] "5.10"

$chisq_df
df 
 3 

$chisq_p_value
[1] "0.1644"

$cramers_v
[1] "0.03"


    Pearson's Chi-squared test

data:  with(subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens,     !rn %in% sil_neg_pam_om_clus4_q), table(factor_inclusivo_real_hist_mas_autperc_bin,     clus_pam_om4))
X-squared = 6.4466, df = 3, p-value = 0.09179

$chisq_statistic
[1] "6.45"

$chisq_df
df 
 3 

$chisq_p_value
[1] "0.0918"

$cramers_v
[1] "0.03"

Tiempo que demora esta sección: 0 minutos

Hicimos una prueba post-hoc usando Bonferroni

Código
ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens|>
  dplyr::count(clus_pam_om4, factor_inclusivo_real_hist_mas_autperc_bin)|>
  dplyr::group_by(clus_pam_om4) |>
  dplyr::mutate(n_prop = paste0(n, " (",scales::percent(n / sum(n), accuracy=.1),")")) |>
  dplyr::select(-n) |>
  tidyr::pivot_wider(names_from = factor_inclusivo_real_hist_mas_autperc_bin, values_from = n_prop, values_fill = "0")|> 
  (\(df) {
        if (interactive()) {mutate(df, across(-1, ~ gsub("%", "", gsub("\\.", ",", .))))|> select(3)|>t()|>  rio::export("clipboard")}
        knitr::kable(df, "markdown", col.names=c("Conglomerados","No se identifica/no pertenece", "Hay reconocimeinto"), caption="Porcentajes por fila, conglomerado vs. Pertenencia/identificación + Reconocimento CONADI PPOO")
      })()
Porcentajes por fila, conglomerado vs. Pertenencia/identificación + Reconocimento CONADI PPOO
Conglomerados No se identifica/no pertenece Hay reconocimeinto
6623, Un trimestre, TSM(4) 4209 (80.2%) 1039 (19.8%)
6612, Un trimestre, TUS(3) 583 (77.7%) 167 (22.3%)
6522, Un semestre TSM(1) 327 (82.0%) 72 (18.0%)
6574, Comorbilidad un trimestre(2) 191 (83.4%) 38 (16.6%)

Tiempo que demora esta sección: 0 minutos

1.1.3.b. Comparación covariables- Mortalidad
Código
# 
invisible("No hay nada, el tiempo promedio de censura es similar")

ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens |> 
  dplyr::mutate(death_time_rec=ifelse(death_time==20,0,1)) |> 
  janitor::tabyl(clus_pam_om6,death_time_rec) |> 
  dplyr::mutate(`1`= paste0(`1`," (", scales::percent(`1`/(`0`+`1`), accuracy=.1),")")) |> 
  dplyr::left_join(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens |> 
  dplyr::group_by(clus_pam_om6) |> 
  dplyr::summarise(mean=sprintf("%1.1f",mean(cens_time))), by="clus_pam_om6") |> 
  dplyr::select(-`0`)|> 
  (\(df) {
        if (interactive()) {mutate(df, across(-1, ~ gsub("%", "", gsub("\\.", ",", .))))|> select(2)|> t()|>  rio::export("clipboard")}
        knitr::kable(df, "markdown", col.names=c("Conglomerado","Mortalidad observada", "Promedio"), caption="Post-hoc, conglomerado vs. Mortalidad y tiempo a censura")
      })()
Post-hoc, conglomerado vs. Mortalidad y tiempo a censura
Conglomerado Mortalidad observada Promedio
6623, Un trimestre, TSM(5) 58 (1.2%) 17.9
6612, Un trimestre, TUS(4) 19 (2.5%) 18.2
6522, Un semestre TSM(2) 8 (2.2%) 17.9
6624, TSM, 1 año después, otras causas(6) 5 (2.1%) 17.8
6574, Comorbilidad un trimestre(3) 6 (2.7%) 18.1
6268, TSM, 1 año después, TSM(1) 3 (1.7%) 18.1

Tiempo que demora esta sección: 0 minutos

Código
ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens |> 
             dplyr::mutate(death_time_rec=ifelse(death_time==20,0,1)) |> 
             janitor::tabyl(death_time_rec,clus_pam_om4) |> 
              janitor::chisq.test(correct=T)
#X-squared = 11.377, df = 3, p-value = 0.009854

chisq_cramerv(
with(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens|> 
             dplyr::mutate(death_time_rec=ifelse(death_time==20,0,1)), table(death_time_rec , clus_pam_om4))
)

fisher.test(
    with(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens|> 
             dplyr::mutate(death_time_rec=ifelse(death_time==20,0,1)), table(death_time_rec , clus_pam_om4), simulate.p.value=T, B=1e5)
)
#p-value = 0.008208

message("Descartando valores negativos en sil width")
chisq_cramerv(
with(subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, !rn %in% sil_neg_pam_om_clus4_q)|> 
             dplyr::mutate(death_time_rec=ifelse(death_time==20,0,1)), table(death_time_rec , clus_pam_om4))
)
# $chisq_statistic
# [1] "11.31"
# 
# $chisq_df
# df 
#  3 
# 
# $chisq_p_value
# [1] "0.0101"
# 
# $cramers_v
# [1] "0.04"

fisher.test(
    with(subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, !rn %in% sil_neg_pam_om_clus4_q)|> 
             dplyr::mutate(death_time_rec=ifelse(death_time==20,0,1)), table(death_time_rec , clus_pam_om4), simulate.p.value=T, B=1e5)
)
#p-value = 0.007751


invisible("no se basa en la distribución chi-cuadrado. Fisher se basa en permutaciones exactas, por lo que no se calculan df.")

#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_
##_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_
tab_cl_mortalidad_pam_om4_q<- 
  ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens |> 
  dplyr::mutate(death_time_rec=ifelse(death_time==20,0,1)) |> 
  janitor::tabyl(death_time_rec,clus_pam_om4) |> 
  as.matrix(ncol=2)

labels_pam_om4_q <- c(
  "6623, Un trimestre, TSM(4)",
  "6612, Un trimestre, TUS(3)",
  "6522, Un semestre TSM(1)",
  "6574, Comorbilidad un trimestre(2)"
)

chisq.posthoc.test(with(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens|> 
             dplyr::mutate(death_time_rec=ifelse(death_time==20,0,1)), table(death_time_rec , clus_pam_om4), simulate.p.value=T, B=1e5))

# Realizar el análisis y crear la tabla directamente
pairwise.prop.test(t(tab_cl_mortalidad_pam_om4_q[,2:5]), p.adjust.method = "holm")$p.value|>
  as.table() |>
  as.data.frame() |>
  rename(Grupo_1 = Var1, Grupo_2 = Var2, p_value = Freq) |>
  filter(!is.na(p_value)) |>
  mutate(
    Grupo_1 = labels_pam_om4_q[as.numeric(Grupo_1)],
    Grupo_2 = labels_pam_om4_q[as.numeric(Grupo_2)],
    p_value = ifelse(p_value <.001, "<.001", sprintf("%1.3f",p_value)) 
  ) |>
  kable(
    col.names = c("Grupo 1", "Grupo 2", "Valor p ajustado"),
    align = "l",
    caption= "Corrección parcial por comparaciones múltiples (Holm–Bonferroni)"
  )

    Pearson's Chi-squared test

data:  janitor::tabyl(dplyr::mutate(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens,     death_time_rec = ifelse(death_time == 20, 0, 1)), death_time_rec,     clus_pam_om4)
X-squared = 11.377, df = 3, p-value = 0.009854

$chisq_statistic
[1] "11.38"

$chisq_df
df 
 3 

$chisq_p_value
[1] "0.0099"

$cramers_v
[1] "0.04"


    Fisher's Exact Test for Count Data

data:  with(dplyr::mutate(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, death_time_rec = ifelse(death_time == 20, 0, 1)), table(death_time_rec, clus_pam_om4), simulate.p.value = T, B = 1e+05)
p-value = 0.008208
alternative hypothesis: two.sided

$chisq_statistic
[1] "11.31"

$chisq_df
df 
 3 

$chisq_p_value
[1] "0.0101"

$cramers_v
[1] "0.04"


    Fisher's Exact Test for Count Data

data:  with(dplyr::mutate(subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, !rn %in% sil_neg_pam_om_clus4_q), death_time_rec = ifelse(death_time == 20, 0, 1)), table(death_time_rec, clus_pam_om4), simulate.p.value = T, B = 1e+05)
p-value = 0.007751
alternative hypothesis: two.sided

  Dimension     Value 6623, Un trimestre, TSM(4) 6612, Un trimestre, TUS(3)
1         0 Residuals           3.34615360812403                  -2.491149
2         0  p values                    0.0066*                   0.101900
3         1 Residuals            -3.346153608124                   2.491149
4         1  p values                    0.0066*                   0.101900
  6522, Un semestre TSM(1) 6574, Comorbilidad un trimestre(2)
1                -1.293403                          -1.429422
2                 1.000000                           1.000000
3                 1.293403                           1.429422
4                 1.000000                           1.000000
Corrección parcial por comparaciones múltiples (Holm–Bonferroni)
Grupo 1 Grupo 2 Valor p ajustado
6623, Un trimestre, TSM(4) 6623, Un trimestre, TSM(4) 0.047
6612, Un trimestre, TUS(3) 6623, Un trimestre, TSM(4) 0.654
6522, Un semestre TSM(1) 6623, Un trimestre, TSM(4) 0.654
6612, Un trimestre, TUS(3) 6612, Un trimestre, TUS(3) 1.000
6522, Un semestre TSM(1) 6612, Un trimestre, TUS(3) 1.000
6522, Un semestre TSM(1) 6522, Un semestre TSM(1) 1.000

Tiempo que demora esta sección: 0 minutos

Código
# Cargar las librerías necesarias
library(survival)
library(ggplot2)

# Crear la variable de supervivencia
surv_obj_4c <- Surv(
  time= ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$death_time,
  event = ifelse(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$death_time== 20,0,1))

# Realizar el análisis de Log-Rank (survdiff)
surv_diff_4c <- survdiff(surv_obj_4c ~ clus_pam_om4,
                      data = ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens)


cat("Diferencia multiplicativa entre cluster TSM 1 trimestre y el resto")
biostat3::survRate(survival::Surv(time = death_time,
                        event = ifelse(death_time==20,0,1)) ~ clus1, 
                   data= ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens|> dplyr::mutate(clus1= ifelse(grepl("Un trimestre, TSM",clus_pam_om4),"1","0")))|> 
    dplyr::mutate(across(c("rate", "lower", "upper"),~sprintf("%1.2f",.*10000))) 
cat("El resto")
cat("Razón entre cluster TSM 1 trimestre y el resto")
epitools::rateratio.midp(c(34, 65, 27103.87, 104000.76))

# Mostrar los resultados del test
print(surv_diff_4c)

pairwise_survdiff(
    formula = as.numeric(surv_obj_4c) ~ clus_pam_om4,
    data = ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens,
    p.adjust.method = "holm"
)

Error in model.frame.default(formula = as.numeric(surv_obj_4c) ~ clus_pam_om4, : las longitudes variables difieren (encontradas para ‘clus_pam_om4’)

Código
message("Sin siluetas negativas")
surv_diff_4c_neg_sil <- survdiff(Surv(time = death_time,
  event = ifelse(death_time==20,0,1)) ~ clus_pam_om4,
  data = subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, !rn %in% sil_neg_pam_om_clus4_q))

# Mostrar los resultados del test
print(surv_diff_4c_neg_sil)

pairwise_survdiff(
    formula = Surv(time = death_time,
                 event = ifelse(death_time==20,0,1)) ~ clus_pam_om4,
    data = subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, !rn %in% sil_neg_pam_om_clus4_q), rho=0,
    p.adjust.method = "holm"
)

# Ajustar el modelo de Kaplan-Meier
km_fit_4c <- survfit(surv_obj_4c ~ clus_pam_om4,
                  data = ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens)

# Extraer los datos del modelo Kaplan-Meier para usar con ggplot
km_data_4c <- data.frame(
  time = km_fit_4c$time,
  surv = km_fit_4c$surv,
  upper = km_fit_4c$upper,
  lower = km_fit_4c$lower,
  strata = rep( c("6035,\nUn trimestre,\nTSM(4)", 
             "6025,\nUn trimestre,\nTUS(3)", 
             "5939,\nUn semestre\nTSM(1)", 
             "5989,\nComorbilidad un\ntrimestre(2)"), km_fit_4c$strata)
)

biostat3::survRate(Surv(time = death_time,
  event = ifelse(death_time==20,0,1)) ~ clus_pam_om4, 
  data= ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens)|> 
  mutate(
    tasa_formateada = sprintf(
      "%s [%s-%s] (%s / %s)",
      gsub("\\.", ",", sprintf("%.2f", rate * 10000)),
      gsub("\\.", ",", sprintf("%.2f", lower * 10000)),
      gsub("\\.", ",", sprintf("%.2f", upper * 10000)),
      event,
      scales::comma(tstop, big.mark = ".", decimal.mark = ",", accuracy = 1)
    )
  )|> 
  select(clus_pam_om4, tasa_formateada)|> 
   (\(df) { rownames(df) <- NULL ; df  })()|>
  (\(df) {
        if (interactive()) { t(df) |> rio::export("clipboard") }
        knitr::kable(df, "markdown", caption="Tasas de mortalidad por conglomerado")
      })()
Diferencia multiplicativa entre cluster TSM 1 trimestre y el resto        clus1     tstop event  rate lower upper
clus1=0     0  27103.87    34 12.54  8.69 17.53
clus1=1     1 104000.76    65  6.25  4.82  7.97
El restoRazón entre cluster TSM 1 trimestre y el resto$data
          Outcome
Predictor  Cases Person-time
  Exposed1    34    27103.87
  Exposed2    65   104000.76
  Total       99   131104.63

$measure
          rate ratio with 95% C.I.
Predictor   estimate     lower     upper
  Exposed1 1.0000000        NA        NA
  Exposed2 0.4970789 0.3304318 0.7615809

$p.value
          two-sided
Predictor   midp.exact         wald
  Exposed1          NA           NA
  Exposed2 0.001621896 0.0007831433

attr(,"method")
[1] "Median unbiased estimate & mid-p exact CI"
Call:
survdiff(formula = surv_obj_4c ~ clus_pam_om4, data = ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens)

                                                   N Observed Expected
clus_pam_om4=6623, Un trimestre, TSM(4)         5248       65    78.48
clus_pam_om4=6612, Un trimestre, TUS(3)          750       19    11.15
clus_pam_om4=6522, Un semestre TSM(1)            399        9     5.97
clus_pam_om4=6574, Comorbilidad un trimestre(2)  229        6     3.40
                                                (O-E)^2/E (O-E)^2/V
clus_pam_om4=6623, Un trimestre, TSM(4)              2.32     11.18
clus_pam_om4=6612, Un trimestre, TUS(3)              5.53      6.23
clus_pam_om4=6522, Un semestre TSM(1)                1.54      1.64
clus_pam_om4=6574, Comorbilidad un trimestre(2)      1.99      2.06

 Chisq= 11.4  on 3 degrees of freedom, p= 0.01 
Call:
survdiff(formula = Surv(time = death_time, event = ifelse(death_time == 
    20, 0, 1)) ~ clus_pam_om4, data = subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, 
    !rn %in% sil_neg_pam_om_clus4_q))

                                                   N Observed Expected
clus_pam_om4=6623, Un trimestre, TSM(4)         5246       65    77.88
clus_pam_om4=6612, Un trimestre, TUS(3)          750       19    11.07
clus_pam_om4=6522, Un semestre TSM(1)            248        6     3.68
clus_pam_om4=6574, Comorbilidad un trimestre(2)  229        6     3.37
                                                (O-E)^2/E (O-E)^2/V
clus_pam_om4=6623, Un trimestre, TSM(4)              2.13     11.29
clus_pam_om4=6612, Un trimestre, TUS(3)              5.68      6.43
clus_pam_om4=6522, Un semestre TSM(1)                1.47      1.53
clus_pam_om4=6574, Comorbilidad un trimestre(2)      2.05      2.12

 Chisq= 11.3  on 3 degrees of freedom, p= 0.01 

    Pairwise comparisons using Log-Rank test 

data:  subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens,  and clus_pam_om4     !rn %in% sil_neg_pam_om_clus4_q) and clus_pam_om4 

                                   6623, Un trimestre, TSM(4)
6612, Un trimestre, TUS(3)         0.028                     
6522, Un semestre TSM(1)           0.438                     
6574, Comorbilidad un trimestre(2) 0.348                     
                                   6612, Un trimestre, TUS(3)
6612, Un trimestre, TUS(3)         -                         
6522, Un semestre TSM(1)           1.000                     
6574, Comorbilidad un trimestre(2) 1.000                     
                                   6522, Un semestre TSM(1)
6612, Un trimestre, TUS(3)         -                       
6522, Un semestre TSM(1)           -                       
6574, Comorbilidad un trimestre(2) 1.000                   

P value adjustment method: holm 
Tasas de mortalidad por conglomerado
clus_pam_om4 tasa_formateada
6623, Un trimestre, TSM(4) 6,25 [4,82-7,97] (65 / 104.001)
6612, Un trimestre, TUS(3) 12,90 [7,77-20,14] (19 / 14.731)
6522, Un semestre TSM(1) 11,41 [5,22-21,67] (9 / 7.886)
6574, Comorbilidad un trimestre(2) 13,37 [4,91-29,10] (6 / 4.487)

Tiempo que demora esta sección: 0 minutos

Código
# ── 1. Paquetes ────────────────────────────────────────────────────────────
library(metafor)   # meta-análisis y estadísticos de heterogeneidad

# ── 2. Datos ───────────────────────────────────────────────────────────────
dat <- tibble::tribble(
  ~grupo,     ~eventos, ~py,
  "G1",         65,     104001,
  "G2",         19,      14731,
  "G3",          9,       7886,
  "G4",          6,       4487
)

# ── 3. Log-tasa y varianza (1/eventos) ─────────────────────────────────────
dat_es <- escalc(measure = "IRLN",     # Incidence Rate, Log-transformed
                 xi = eventos, ti = py,
                 data = dat)

# ── 4. Meta-análisis de efectos fijos ──────────────────────────────────────
res <- rma(yi, vi, data = dat_es, method = "FE")

# ── 5. Estadísticos globales ───────────────────────────────────────────────
pooled_rate <- exp(coef(res))              # tasa agrupada (misma unidad que yi)
Q       <- res$QE                          # Q de Cochran
p_Q     <- res$QEp                         # p-valor

# ── 6. Comparaciones post-hoc por pares (z en escala log) ─────────────────-
pairs <- combn(nrow(dat_es), 2, simplify = FALSE)
pw <- lapply(pairs, function(idx) {
  i <- idx[1]; j <- idx[2]
  diff  <- dat_es$yi[i] - dat_es$yi[j]           # Δ log-tasa
  se    <- sqrt(dat_es$vi[i] + dat_es$vi[j])     # varianzas independientes
  z     <- diff / se
  p_raw <- 2 * pnorm(-abs(z))
  tibble(grupo1 = dat$grupo[i],
         grupo2 = dat$grupo[j],
         rate_ratio = exp(diff),                # RR entre las dos tasas
         z, p_raw)
}) |>
  bind_rows() |>
  mutate(p_Holm = p.adjust(p_raw, method = "holm"))

# ── 7. Resultado compacto ─────────────────────────────────────────────────
print(res)      # aporta tasa agrupada, IC95 %, Q, p_Q
pw              # tabla con comparaciones post-hoc

Fixed-Effects Model (k = 4)

I^2 (total heterogeneity / total variability):   72.75%
H^2 (total variability / sampling variability):  3.67

Test for Heterogeneity:
Q(df = 3) = 11.0105, p-val = 0.0117

Model Results:

estimate      se      zval    pval    ci.lb    ci.ub      
 -7.1379  0.1005  -71.0211  <.0001  -7.3349  -6.9409  *** 

---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

# A tibble: 6 × 6
  grupo1 grupo2 rate_ratio       z   p_raw p_Holm
  <chr>  <chr>       <dbl>   <dbl>   <dbl>  <dbl>
1 G1     G2          0.485 -2.78   0.00547 0.0328
2 G1     G3          0.548 -1.69   0.0904  0.373 
3 G1     G4          0.467 -1.78   0.0747  0.373 
4 G2     G3          1.13   0.302  0.762   1     
5 G2     G4          0.965 -0.0771 0.939   1     
6 G3     G4          0.853 -0.301  0.764   1     

Tiempo que demora esta sección: 0 minutos

Código
# Crear el gráfico de Kaplan-Meier con ggplot2
ggplot(km_data_4c, aes(x = time, y = surv, color = strata)) +
  geom_step(size = 1.2) +  # Curvas de supervivencia
  #geom_ribbon(aes(ymin = lower, ymax = upper, fill = strata), alpha = 0.2, color = NA) +  # Intervalos de confianza
  labs(
    x = "Tiempo (meses)",
    y = "Probabilidad de Supervivencia",
    color = "Grupo",
    fill = "Grupo"
  ) +
  theme_minimal() +
  ylim(c(0.9,1))+
  theme(legend.position = "bottom")

Tiempo que demora esta sección: 0 minutos

Código
def_enc17_21 <- readr::read_delim("_output/def_enc.csv", 
delim = ";", escape_double = FALSE, trim_ws = TRUE)

# DIAG1= Diagnóstico principal del usuario
# DIAG2= Causa externa de hospitalización
def_enc17_21 <-
def_enc17_21[,c("RUN", "DIAG1", "DIAG2")]

# Suicidio (X60-X84)
# Homicidio (X85-X99, Y00-Y09)
# Intención indeterminada (Y10-Y34)
# Armas de fuego (W32-W34)
# Legal intervention (Y35.0-Y35.4, Y35.6-Y35.7)
# Terrorism (U01-U03
# Specific Y codes (Y87.0, Y87.1, Y87.2, Y89.9, Y86, Y89.0)

invisible(paste0(" Fowler, K. A., Jack, S. P., Lyons, B. H., Betz, C. J., & Petrosky, E. (2018). Surveillance for Violent Deaths —
National Violent Death Reporting System, 18 States, 2014. MMWR Surveillance Summaries, 67(2), 1. https://doi.org/10.15585/mmwr.ss6702a1"))

pattern <- "^(X(6[0-9]|7[0-9]|8[0-4])\\d|X(8[5-9]|9[0-9])\\d|Y0[0-9]\\d|Y(1[0-9]|2[0-9]|3[0-4])\\d|W3[2-4]\\d|Y35[0-46-7]|Y87[012]\\d|Y89[09]\\d|Y86$|U0[1-3]\\d)"
def_enc17_21 |> 
  dplyr::filter(RUN %in% subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, filter= death_time_rec==1)$run) |> 
  #dplyr::filter(!RUN %in% runs_6025$run) |>
  dplyr::select(RUN, DIAG1, DIAG2) |> 
  reshape2::melt(id.vars="RUN") |> 
  dplyr::filter(!is.na(value)) |> 
  # janitor::tabyl(value) |> 
  # arrange(desc(n)) |> 
  dplyr::mutate(violent_death = grepl(pattern, value, ignore.case = F)) |> 
  janitor::tabyl(violent_death) 
# violent_death   n   percent
#        FALSE 122 0.7820513
#         TRUE  34 0.2179487

#clus_pam_om4      tstop event  rate lower upper
# 6623, Un trimestre, TSM(4) 104000.760    65  6.25  4.82  7.97
# 6612, Un trimestre, TUS(3)  14730.962    19 12.90  7.77 20.14
# 6522, Un semestre TSM(1)   7885.631     9 11.41  5.22 21.67
# 6574, Comorbilidad un trimestre(2)   4487.281     6 13.37  4.91 29.10
# 
# Fuente: https://www.suseso.cl/612/articles-18722_archivo_01.pdf

def_enc17_21 |> 
  dplyr::filter(RUN %in% subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, filter= death_time_rec==1)$run) |> 
  dplyr::select(RUN, DIAG1, DIAG2) |>
  dplyr::left_join(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens[, c("run", "clus_pam_om4")], by=c("RUN"="run"), multiple="first") |> 
  dplyr::group_by(clus_pam_om4) |> 
  dplyr::summarise(violent_death1 = sum(grepl(pattern, DIAG1, ignore.case = F)),
  violent_death2 = sum(grepl(pattern, DIAG2, ignore.case = F))) |> 
  ungroup() |> 
  dplyr::mutate(violent_death = violent_death1 + violent_death2) |>
  dplyr::mutate(total = ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens |> group_by(clus_pam_om4) |> count() |> pull(n), perc= violent_death/total) |>
  dplyr::mutate(pq= c(104000.76, 14730.962, 7885.631, 4487.281)) |>
  dplyr::mutate(ir= (violent_death/pq)*1000) |>
  knitr::kable("markdown", caption="Tasas de mortalidad por conglomerado y causa de muerte, muertes violentas")



  def_enc17_21 |> 
  dplyr::filter(RUN %in% subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, filter= death_time_rec==1)$run) |> 
  dplyr::select(RUN, DIAG1, DIAG2) |>
  dplyr::left_join(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens[, c("run", "clus_pam_om4")], by=c("RUN"="run"), multiple="first") |>
  dplyr::select(RUN, clus_pam_om4, DIAG1, DIAG2) |> 
  mutate(
    categoria1 = case_when(
      grepl("^X(6[0-9]|7[0-9]|8[0-4])", DIAG1) ~ "Lesiones autoinfligidas intencionales",
      grepl("^V[0-9]{2}", DIAG1) ~ "Accidentes de tránsito",
      grepl("^(W[0-9]{2}|X[0-5][0-9])", DIAG1) ~ "Otras causas externas accidentales",
      grepl("^(X(8[5-9]|9[0-9])|Y0[0-9])", DIAG1) ~ "Agresiones",
      grepl("^Y8[5-9]", DIAG1) ~ "Secuelas de causas externas",
      grepl("^Y([4-7][0-9]|8[0-4])", DIAG1) ~ "Complicaciones atención médica",
      TRUE ~ "Otras causas no especificadas"
    )
  ) |>
    mutate(
    categoria2 = case_when(
      grepl("^X(6[0-9]|7[0-9]|8[0-4])", DIAG2) ~ "Lesiones autoinfligidas intencionales",
      grepl("^V[0-9]{2}", DIAG2) ~ "Accidentes de tránsito",
      grepl("^(W[0-9]{2}|X[0-5][0-9])", DIAG2) ~ "Otras causas externas accidentales",
      grepl("^(X(8[5-9]|9[0-9])|Y0[0-9])", DIAG2) ~ "Agresiones",
      grepl("^Y8[5-9]", DIAG2) ~ "Secuelas de causas externas",
      grepl("^Y([4-7][0-9]|8[0-4])", DIAG2) ~ "Complicaciones atención médica",
      TRUE ~ "Otras causas no especificadas"
    )
  ) |>
  group_by(clus_pam_om4) |>
   summarise(
      suicidios = sum(categoria1 == "Lesiones autoinfligidas intencionales" |
      categoria2 == "Lesiones autoinfligidas intencionales", na.rm = TRUE),
      accidentes_transito = sum(categoria1 == "Accidentes de tránsito" |
      categoria2 == "Accidentes de tránsito", na.rm = TRUE),
      otras_causas_accidentales = sum(categoria1 == "Otras causas externas accidentales" |
      categoria2 == "Otras causas externas accidentales", na.rm = TRUE),
      agresiones = sum(categoria1 == "Agresiones" |
      categoria2 == "Agresiones", na.rm = TRUE),
      secuelas = sum(categoria1 == "Secuelas de causas externas" |
      categoria2 == "Secuelas de causas externas", na.rm = TRUE),
      complicaciones = sum(categoria1 == "Complicaciones atención médica" |
      categoria2 == "Complicaciones atención médica", na.rm = TRUE),
      otras_no_especificadas = sum(categoria1 == "Otras causas no especificadas" |
      categoria2 == "Otras causas no especificadas", na.rm = TRUE),
      todas_menos_otras = sum(
      categoria1 %in% c("Lesiones autoinfligidas intencionales", "Accidentes de tránsito", "Agresiones") |
      categoria2 %in% c("Lesiones autoinfligidas intencionales", "Accidentes de tránsito", "Agresiones"),
      na.rm = TRUE
      ),
      .groups = "drop"
  ) |> 
    dplyr::mutate(total = ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens |> group_by(clus_pam_om4) |> count() |> pull(n), perc= suicidios/total, perc_todas_menos_otras=todas_menos_otras/total) |>
  dplyr::mutate(pq= c(104000.76, 14730.962, 7885.631, 4487.281)) |>
  dplyr::mutate(ir= (suicidios/pq)*10000, ir_todas_menos_otras=(todas_menos_otras/pq)*10000) |>
  knitr::kable("markdown", caption="Tasas de mortalidad por conglomerado y causa de muerte", col.names=c("Conglomerado","Suicidio","Accidentes de tránsito","Otras causas externas accidentales","Agresiones","Secuelas de causas externas","Complicaciones atención médica","Otras causas no especificadas","Todas menos otras","Total","Proporción suicidio","Proporción todas menos otras", "pq", "IR suicidio", "IR todas menos otras"))
 violent_death   n   percent
         FALSE 122 0.7820513
          TRUE  34 0.2179487
Tasas de mortalidad por conglomerado y causa de muerte, muertes violentas
clus_pam_om4 violent_death1 violent_death2 violent_death total perc pq ir
6623, Un trimestre, TSM(4) 0 24 24 5248 0.0045732 104000.760 0.2307675
6612, Un trimestre, TUS(3) 0 5 5 750 0.0066667 14730.962 0.3394211
6522, Un semestre TSM(1) 0 2 2 399 0.0050125 7885.631 0.2536259
6574, Comorbilidad un trimestre(2) 0 3 3 229 0.0131004 4487.281 0.6685563
Tasas de mortalidad por conglomerado y causa de muerte
Conglomerado Suicidio Accidentes de tránsito Otras causas externas accidentales Agresiones Secuelas de causas externas Complicaciones atención médica Otras causas no especificadas Todas menos otras Total Proporción suicidio Proporción todas menos otras pq IR suicidio IR todas menos otras
6623, Un trimestre, TSM(4) 19 3 15 1 0 0 65 23 5248 0.0036204 0.0043826 104000.760 1.826910 2.211522
6612, Un trimestre, TUS(3) 4 4 1 1 0 0 19 9 750 0.0053333 0.0120000 14730.962 2.715369 6.109581
6522, Un semestre TSM(1) 0 2 0 2 0 0 9 4 399 0.0000000 0.0100251 7885.631 0.000000 5.072517
6574, Comorbilidad un trimestre(2) 2 0 2 1 0 0 6 3 229 0.0087336 0.0131004 4487.281 4.457042 6.685563

Tiempo que demora esta sección: 0 minutos

1.1.3.c. Comparación covariables- no RM vs. RM
Código
chisq_cramerv(table(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$clus_pam_om4,ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$codigo_region_rec_base))
# $chisq_statistic
# [1] "43.38"
# 
# $chisq_df
# df 
#  3 
# 
# $chisq_p_value
# [1] "<0.001"
# 
# $cramers_v
# [1] "0.08"

message("Descartando valores negativos en sil width")
chisq_cramerv(
with(subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, !rn %in% sil_neg_pam_om_clus4_q), table(codigo_region_rec_base , clus_pam_om4))
)
# $chisq_statistic
# [1] "41.60"
# 
# $chisq_df
# df 
#  3 
# 
# $chisq_p_value
# [1] "<0.001"
# 
# $cramers_v
# [1] "0.08"

table(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$clus_pam_om4,ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$codigo_region_rec_base)|>
    data.frame()|>
    dplyr::group_by(Var1)|>
    dplyr::mutate(perc= scales::percent(Freq/sum(Freq), accuracy=.1))|>
    dplyr::ungroup()|> 
    dplyr::mutate(Freq= Freq)|>
    dplyr::mutate(fp= paste0(Freq, " (", perc,")" ))|>
    dplyr::select(-Freq, -perc)|> 
    tidyr::pivot_wider(names_from="Var2",values_from="fp")|> 
  (\(df) {
        if (interactive()) {mutate(df, across(-1, ~ gsub("%", "", gsub("\\.", ",", .))))|>  select(c(1,3)) |> t()|>  rio::export("clipboard")}
        knitr::kable(df, "markdown", caption="Frecuencias absolutas y relativas por fila", col.names= c("Conglomerados", "Fuera de RM", "En RM"))
      })()
$chisq_statistic
[1] "43.38"

$chisq_df
df 
 3 

$chisq_p_value
[1] "<0.001"

$cramers_v
[1] "0.08"

$chisq_statistic
[1] "41.60"

$chisq_df
df 
 3 

$chisq_p_value
[1] "<0.001"

$cramers_v
[1] "0.08"
Frecuencias absolutas y relativas por fila
Conglomerados Fuera de RM En RM
6623, Un trimestre, TSM(4) 2796 (53.3%) 2452 (46.7%)
6612, Un trimestre, TUS(3) 476 (63.5%) 274 (36.5%)
6522, Un semestre TSM(1) 202 (50.6%) 197 (49.4%)
6574, Comorbilidad un trimestre(2) 96 (41.9%) 133 (58.1%)

Tiempo que demora esta sección: 0 minutos

Código
pairwise_chisq_gof_test(table(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$clus_pam_om4,ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$codigo_region_rec_base), p.adjust.method="holm")|> 
  knitr::kable("markdown", caption="Dependencia categórica sol. 4 conglomerados, por pares de categorías en RM")
Dependencia categórica sol. 4 conglomerados, por pares de categorías en RM
n group1 group2 statistic p df p.adj p.adj.signif
2 grp1 grp2 1644.9877751 0.000000 1 0.00e+00 ****
2 grp1 grp3 2244.4416278 0.000000 1 0.00e+00 ****
2 grp1 grp4 2520.7468880 0.000000 1 0.00e+00 ****
2 grp1 grp5 22.5487805 0.000002 1 1.44e-05 ****
2 grp1 grp6 2071.8188925 0.000000 1 0.00e+00 ****
2 grp1 grp7 2256.8663548 0.000000 1 0.00e+00 ****
2 grp1 grp8 2421.1570502 0.000000 1 0.00e+00 ****
2 grp2 grp3 110.7315634 0.000000 1 0.00e+00 ****
2 grp2 grp4 252.4475524 0.000000 1 0.00e+00 ****
2 grp2 grp5 1333.5300546 0.000000 1 0.00e+00 ****
2 grp2 grp6 54.4053333 0.000000 1 0.00e+00 ****
2 grp2 grp7 115.6627043 0.000000 1 0.00e+00 ****
2 grp2 grp8 193.1839080 0.000000 1 0.00e+00 ****
2 grp3 grp4 37.7046980 0.000000 1 0.00e+00 ****
2 grp3 grp5 1907.4981161 0.000000 1 0.00e+00 ****
2 grp3 grp6 10.8907563 0.000966 1 2.90e-03 **
2 grp3 grp7 0.0626566 0.802000 1 8.02e-01 ns
2 grp3 grp8 14.2119403 0.000163 1 9.78e-04 ***
2 grp4 grp5 2178.4678179 0.000000 1 0.00e+00 ****
2 grp4 grp6 85.6324324 0.000000 1 0.00e+00 ****
2 grp4 grp7 34.8156997 0.000000 1 0.00e+00 ****
2 grp4 grp8 5.9781659 0.014500 1 2.90e-02 *
2 grp5 grp6 1740.1628760 0.000000 1 0.00e+00 ****
2 grp5 grp7 1919.6017365 0.000000 1 0.00e+00 ****
2 grp5 grp8 2080.3717602 0.000000 1 0.00e+00 ****
2 grp6 grp7 12.5881104 0.000388 1 1.94e-03 **
2 grp6 grp8 48.8476658 0.000000 1 0.00e+00 ****
2 grp7 grp8 12.4121212 0.000427 1 1.94e-03 **

Tiempo que demora esta sección: 0 minutos

Código
chisq.posthoc.test(table(
    ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$clus_pam_om4,
    ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens$codigo_region_rec_base
  ))|> 
  (\(df) { dplyr::mutate_at(df, 3:ncol(df), ~ round(as.numeric(gsub("\\*", "", .)), 3))
  })()|>
  group_by(Dimension)|>
  (\(df) { summarise(df, across(2:(ncol(df)-1), ~ paste0(first(sprintf("%1.2f", .)), " (p=", last(sprintf("%1.3f", .)), ")")))
  })()|>
  (\(df) { dplyr::mutate_at(df, 2:length(names(df)), ~ gsub("p\\=0.000)", "p<0.001)", .))
  })()|>
  knitr::kable("markdown", caption = "Comparación post-hoc, conglomerado-RM vs. No-RM")
Comparación post-hoc, conglomerado-RM vs. No-RM
Dimension noRM RM
6522, Un semestre TSM(1) -1.34 (p=1.000) 1.34 (p=1.000)
6574, Comorbilidad un trimestre(2) -3.69 (p=0.002) 3.69 (p=0.002)
6612, Un trimestre, TUS(3) 5.59 (p<0.001) -5.59 (p<0.001)
6623, Un trimestre, TSM(4) -1.92 (p=0.443) 1.92 (p=0.443)

Tiempo que demora esta sección: 0 minutos

1.1.3.e. Comparación covariables- Región
Código
tab_cluster_region_pam_om4_q<-
ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens |> 
  dplyr::inner_join(data_long_establecimiento_2024_std[,c("ESTAB_HOMO", "codigo_region", "nivel_de_atencion", "nivel_de_complejidad")], 
                    by = c("estab_homo_base" = "ESTAB_HOMO"), multiple = "first") |> 
  janitor::tabyl(codigo_region, clus_pam_om4) |> 
  janitor::adorn_percentages("col") |> 
  janitor::adorn_rounding(digits = 2)

#colnames(tab_cluster_region_pam_om4_q)<- c("reg", "c1", "c4", "c3", "c5", "c6", "c7", "c8", "c9", "c2")
cod_reg_homo_pam_om4_q<-
data.frame(
  codigo_region = 1:16,
  nombre_region = c(
    "Región de Tarapacá",
    "Región de Antofagasta",
    "Región de Atacama",
    "Región de Coquimbo",
    "Región de Valparaíso",
    "Región del Libertador General Bernardo O'Higgins",
    "Región del Maule",
    "Región del Biobío",
    "Región de La Araucanía",
    "Región de Los Lagos",
    "Región de Aysén del General Carlos Ibáñez del Campo",
    "Región de Magallanes y de la Antártica Chilena",
    "Región Metropolitana de Santiago",
    "Región de Los Ríos",
    "Región de Arica y Parinacota",
    "Región de Ñuble"
  ),
  stringsAsFactors = FALSE
)

dplyr::mutate(tab_cluster_region_pam_om4_q, promedio_fila = rowMeans(across(2:length(colnames(tab_cluster_region_pam_om4_q))))) |> 
  dplyr::arrange(desc(promedio_fila)) |> 
  dplyr::left_join(cod_reg_homo_pam_om4_q, by="codigo_region") |> 
  dplyr::select(codigo_region, nombre_region, everything()) |> 
  dplyr::select(-promedio_fila) |> 
  dplyr::mutate_at(3:(length(colnames(tab_cluster_region_pam_om4_q))+1),~scales::percent(.))|> 
  knitr::kable(caption="Porcentaje por región")
Porcentaje por región
codigo_region nombre_region 6623, Un trimestre, TSM(4) 6612, Un trimestre, TUS(3) 6522, Un semestre TSM(1) 6574, Comorbilidad un trimestre(2)
13 Región Metropolitana de Santiago 45% 35% 46% 56%
5 Región de Valparaíso 8% 13% 11% 7%
10 Región de Los Lagos 6% 19% 4% 10%
8 Región del Biobío 10% 8% 9% 9%
9 Región de La Araucanía 5% 4% 5% 5%
6 Región del Libertador General Bernardo O’Higgins 4% 3% 5% 2%
7 Región del Maule 4% 3% 3% 3%
1 Región de Tarapacá 2% 2% 2% 2%
2 Región de Antofagasta 2% 1% 4% 1%
11 Región de Aysén del General Carlos Ibáñez del Campo 2% 2% 1% 3%
14 Región de Los Ríos 3% 3% 2% 0%
16 Región de Ñuble 2% 2% 3% 1%
12 Región de Magallanes y de la Antártica Chilena 1% 2% 3% 1%
3 Región de Atacama 2% 1% 3% 0%
4 Región de Coquimbo 1% 1% 1% 0%
15 Región de Arica y Parinacota 2% 0% 1% 0%

Tiempo que demora esta sección: 0 minutos

Código
tab_clus_reg_pam_om4_q<-
ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens |> 
    dplyr::inner_join(data_long_establecimiento_2024_std[,c("ESTAB_HOMO", "codigo_region", "nivel_de_atencion", "nivel_de_complejidad")], 
                      by = c("estab_homo_base" = "ESTAB_HOMO"), multiple = "first") |> 
    janitor::tabyl(codigo_region, clus_pam_om4)

chisq_cramerv(tab_clus_reg_pam_om4_q[,-1])
# $chisq_statistic
# [1] "272.15"
# 
# $chisq_df
# df 
# 45 
# 
# $chisq_p_value
# [1] "<0.001"
# 
# $cramers_v
# [1] "0.12"
janitor::fisher.test(tab_clus_reg_pam_om4_q, simulate.p.value=T, B=1e5)
#p-value = 1e-05

message("Descartando valores negativos en sil width")
chisq_cramerv(
with(subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, !rn %in% sil_neg_pam_om_clus4_q)|> 
    dplyr::inner_join(data_long_establecimiento_2024_std[,c("ESTAB_HOMO", "codigo_region", "nivel_de_atencion", "nivel_de_complejidad")], by = c("estab_homo_base" = "ESTAB_HOMO"), multiple = "first") , table(codigo_region , clus_pam_om4))
)
# $chisq_statistic
# [1] "272.56"
# 
# $chisq_df
# df 
# 45 
# 
# $chisq_p_value
# [1] "<0.001"
# 
# $cramers_v
# [1] "0.12"
$chisq_statistic
[1] "272.15"

$chisq_df
df 
45 

$chisq_p_value
[1] "<0.001"

$cramers_v
[1] "0.12"


    Fisher's Exact Test for Count Data with simulated p-value (based on
    1e+05 replicates)

data:  tab_clus_reg_pam_om4_q
p-value = 1e-05
alternative hypothesis: two.sided

$chisq_statistic
[1] "272.56"

$chisq_df
df 
45 

$chisq_p_value
[1] "<0.001"

$cramers_v
[1] "0.12"

Tiempo que demora esta sección: 0 minutos

Por macrozona
Código
tab_clus_macrozona_pam_om4_q<-
ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens |> 
  dplyr::inner_join(data_long_establecimiento_2024_std[,c("ESTAB_HOMO", "codigo_region", "nivel_de_atencion", "nivel_de_complejidad")], 
                    by = c("estab_homo_base" = "ESTAB_HOMO"), multiple = "first") |> 
dplyr::mutate(macrozona = dplyr::case_when(
  codigo_region %in% c(15, 1, 2, 3) ~ "Macrozona Norte",
  codigo_region %in% c(4, 5)~ "Macrozona Centro",
  codigo_region %in% c(6, 7, 16, 8) ~ "Macrozona Centro Sur",
  codigo_region %in% c(9, 14, 10) ~ "Macrozona Sur",
  codigo_region %in% c(11, 12) ~ "Macrozona Austral",
  TRUE ~ "RM"  # En caso de que algún código no esté especificado
)) |> 
  janitor::tabyl(macrozona, clus_pam_om4) 

chisq_cramerv(dplyr::filter(tab_clus_macrozona_pam_om4_q,macrozona!="RM")[,-1])
# $chisq_statistic
# [1] "95.23"
# 
# $chisq_df
# df 
# 12 
# 
# $chisq_p_value
# [1] "<0.001"
# 
# $cramers_v
# [1] "0.09"

message("Descartando valores negativos en sil width")
chisq_cramerv(
with(subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, !rn %in% sil_neg_pam_om_clus4_q)|> 
  dplyr::inner_join(data_long_establecimiento_2024_std[,c("ESTAB_HOMO", "codigo_region", "nivel_de_atencion", "nivel_de_complejidad")], 
                    by = c("estab_homo_base" = "ESTAB_HOMO"), multiple = "first") |> 
dplyr::mutate(macrozona = dplyr::case_when(
  codigo_region %in% c(15, 1, 2, 3) ~ "Macrozona Norte",
  codigo_region %in% c(4, 5)~ "Macrozona Centro",
  codigo_region %in% c(6, 7, 16, 8) ~ "Macrozona Centro Sur",
  codigo_region %in% c(9, 14, 10) ~ "Macrozona Sur",
  codigo_region %in% c(11, 12) ~ "Macrozona Austral",
  TRUE ~ "RM"  # En caso de que algún código no esté especificado
)) |> dplyr::filter(macrozona!="RM") , table(macrozona, clus_pam_om4))
)
# $chisq_statistic
# [1] "99.18"
# 
# $chisq_df
# df 
# 12 
# 
# $chisq_p_value
# [1] "<0.001"
# 
# $cramers_v
# [1] "0.10"
tab_clus_macrozona_pam_om4_q|> 
  dplyr::filter(macrozona!="RM")|> 
  janitor::adorn_percentages("col")|> 
  janitor::adorn_rounding(digits = 3)|> 
    dplyr::mutate(across(-macrozona, ~ sprintf("%d (%.1f%%)", 
  dplyr::filter(tab_clus_macrozona_pam_om4_q,macrozona!="RM")[[cur_column()]], . * 100)))|>
  mutate(macrozona = factor(macrozona, levels = c("Macrozona Norte", "Macrozona Centro", "Macrozona Centro Sur", "Macrozona Sur", "Macrozona Austral")))|> 
  arrange(macrozona)|>
  (\(df) {
  if (interactive()) {mutate(df, across(-macrozona, ~ gsub("%", "", gsub("\\.", ",", .))))|> rio::export("clipboard")}
  knitr::kable(df, caption="Porcentajes por columna, conglomerado vs. macrozona")
  })() 
$chisq_statistic
[1] "95.23"

$chisq_df
df 
12 

$chisq_p_value
[1] "<0.001"

$cramers_v
[1] "0.09"

$chisq_statistic
[1] "99.18"

$chisq_df
df 
12 

$chisq_p_value
[1] "<0.001"

$cramers_v
[1] "0.10"
Porcentajes por columna, conglomerado vs. macrozona
macrozona 6623, Un trimestre, TSM(4) 6612, Un trimestre, TUS(3) 6522, Un semestre TSM(1) 6574, Comorbilidad un trimestre(2)
Macrozona Norte 436 (15.1%) 31 (6.4%) 34 (15.9%) 7 (7.0%)
Macrozona Centro 483 (16.7%) 103 (21.1%) 47 (22.0%) 15 (15.0%)
Macrozona Centro Sur 1067 (36.9%) 123 (25.3%) 75 (35.0%) 36 (36.0%)
Macrozona Sur 724 (25.1%) 200 (41.1%) 45 (21.0%) 34 (34.0%)
Macrozona Austral 178 (6.2%) 30 (6.2%) 13 (6.1%) 8 (8.0%)

Tiempo que demora esta sección: 0 minutos

Código
chisq.posthoc.test(dplyr::filter(tab_clus_macrozona_pam_om4_q, macrozona != "RM")[-1])|>
  (\(df) {dplyr::mutate_at(df, 3:ncol(df), ~ round(as.numeric(gsub("\\*", "", .)), 3))})()|>
  group_by(Dimension)|>
  (\(df) {summarise(df, across(2:(ncol(df) - 1), ~paste0(first(sprintf("%1.2f", .)), " (p=", last(sprintf("%1.3f", .)), ")")))})()|>
  (\(df) {dplyr::mutate_at(df, 2:length(names(df)), ~gsub("p\\=0.000)", "p<0.001)", .))})()|>
  dplyr::mutate(Dimension= dplyr::filter(tab_clus_macrozona_pam_om4_q, macrozona!="RM") |> pull(macrozona))|>
  mutate(Dimension = factor(Dimension, levels = c("Macrozona Norte", "Macrozona Centro", "Macrozona Centro Sur", "Macrozona Sur", "Macrozona Austral")))|> 
  arrange(Dimension)|>
  knitr::kable("markdown", caption = "Comparación post-hoc, conglomerado-Macrozona")
Comparación post-hoc, conglomerado-Macrozona
Dimension 6623, Un trimestre, TSM(4) 6612, Un trimestre, TUS(3) 6522, Un semestre TSM(1) 6574, Comorbilidad un trimestre(2)
Macrozona Norte 4.44 (p<0.001) -5.09 (p<0.001) 0.93 (p=1.000) -1.99 (p=0.927)
Macrozona Centro -2.55 (p=0.216) 2.23 (p=0.514) 1.74 (p=1.000) -0.68 (p=1.000)
Macrozona Centro Sur 4.05 (p=0.001) -4.96 (p<0.001) -0.07 (p=1.000) 0.16 (p=1.000)
Macrozona Sur -5.49 (p<0.001) 7.39 (p<0.001) -2.09 (p=0.738) 1.55 (p=1.000)
Macrozona Austral -0.21 (p=1.000) -0.05 (p=1.000) -0.08 (p=1.000) 0.75 (p=1.000)

Tiempo que demora esta sección: 0 minutos

Código
pairwise_chisq_gof_test(dplyr::filter(tab_clus_macrozona_pam_om4_q,macrozona!="RM")[-1], p.adjust.method="holm")|>
  knitr::kable("markdown", caption="Dependencia categórica sol. 4 conglomerados, por pares de categorías en Macrozona (corrección Holm-Bonferroni)")

#Groups sharing a letter are not significantlt different (alpha = 0.05)
Dependencia categórica sol. 4 conglomerados, por pares de categorías en Macrozona (corrección Holm-Bonferroni)
n group1 group2 statistic p df p.adj p.adj.signif
3375 6623, Un trimestre, TSM(4) 6612, Un trimestre, TUS(3) 82.770093 0.00e+00 4 0.000000 ****
3102 6623, Un trimestre, TSM(4) 6522, Un semestre TSM(1) 4.792214 3.09e-01 4 0.314000 ns
2988 6623, Un trimestre, TSM(4) 6574, Comorbilidad un trimestre(2) 8.032418 9.04e-02 4 0.271000 ns
701 6612, Un trimestre, TUS(3) 6522, Un semestre TSM(1) 36.713774 2.00e-07 4 0.000001 ****
587 6612, Un trimestre, TUS(3) 6574, Comorbilidad un trimestre(2) 6.621124 1.57e-01 4 0.314000 ns
314 6522, Un semestre TSM(1) 6574, Comorbilidad un trimestre(2) 10.749851 2.95e-02 4 0.118000 ns

Tiempo que demora esta sección: 0 minutos

1.1.3.f. Comparación covariables- Sexo
Código
tab_clus_sexo_pam_om4_q<-  
  ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens |> 
    janitor::tabyl(glosa_sexo, clus_pam_om4 )

chisq_cramerv(tab_clus_sexo_pam_om4_q[,-1])
# $chisq_statistic
# [1] "268.78"
# 
# $chisq_df
# df 
#  3 
# 
# $chisq_p_value
# [1] "<0.001"
# 
# $cramers_v
# [1] "0.20"

message("Descartando valores negativos en sil width")
chisq_cramerv(with(subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, !rn %in% sil_neg_pam_om_clus4_q), table(glosa_sexo, clus_pam_om4))
)
# $chisq_statistic
# [1] "268.86"
# 
# $chisq_df
# df 
#  3 
# 
# $chisq_p_value
# [1] "<0.001"
# 
# $cramers_v
# [1] "0.20"

tab_clus_sexo_pam_om4_q|> 
  janitor::adorn_percentages("col") |> 
  janitor::adorn_rounding(digits = 3) |> 
  dplyr::mutate(across(-glosa_sexo, ~sprintf("%d (%.1f%%)", tab_clus_sexo_pam_om4_q[[cur_column()]],.*100)))|>
  #dplyr::mutate_at(2:ncol(.),~scales::percent(.)) |> 
  knitr::kable(caption="Porcentajes por columna, conglomerado vs. sexo")
$chisq_statistic
[1] "268.78"

$chisq_df
df 
 3 

$chisq_p_value
[1] "<0.001"

$cramers_v
[1] "0.20"

$chisq_statistic
[1] "268.86"

$chisq_df
df 
 3 

$chisq_p_value
[1] "<0.001"

$cramers_v
[1] "0.20"
Porcentajes por columna, conglomerado vs. sexo
glosa_sexo 6623, Un trimestre, TSM(4) 6612, Un trimestre, TUS(3) 6522, Un semestre TSM(1) 6574, Comorbilidad un trimestre(2)
HOMBRE 2163 (41.2%) 521 (69.5%) 159 (39.8%) 158 (69.0%)
MUJER 3085 (58.8%) 229 (30.5%) 240 (60.2%) 71 (31.0%)

Tiempo que demora esta sección: 0 minutos

Código
chisq.posthoc.test(tab_clus_sexo_pam_om4_q[-1]) |> 
  dplyr::mutate(Dimension = rep(c("HOMBRE", "MUJER"), each=2)) |> 
  dplyr::filter(Dimension == "MUJER") |>
  (\(df) dplyr::mutate(df, across(3:ncol(df), ~ dplyr::case_when(
    Value == "Residuals" ~ sprintf("%1.2f", as.numeric(.x)), 
    Value == "p values" ~ sprintf("%1.3f", as.numeric(gsub("\\*", "", .x)))
  ))))()|>
  (\(df) dplyr::mutate(df, across(3:ncol(df), ~ dplyr::case_when(
    Value == "p values" & .x == "0.000" ~ "<0.001", TRUE ~ .x
  ))))()|>
  t()|>
  (\(df) {
    colnames(df) <- df[1, ]
    df[-1, , drop = FALSE]
  })()|> 
  knitr::kable("markdown", caption="Post-hoc, conglomerado vs. sexo")
Post-hoc, conglomerado vs. sexo
MUJER MUJER
Value Residuals p values
6623, Un trimestre, TSM(4) 13.01 <0.001
6612, Un trimestre, TUS(3) -14.12 <0.001
6522, Un semestre TSM(1) 2.25 0.194
6574, Comorbilidad un trimestre(2) -7.33 <0.001

Tiempo que demora esta sección: 0 minutos

Código
pairwise_chisq_gof_test(tab_clus_sexo_pam_om4_q[-1], p.adjust.method="holm")|> 
    dplyr::mutate(p.adj= dplyr::case_when(p.adj<0.001~ "<0.001",T~ sprintf("%1.3f",p.adj)))|> 
  knitr::kable("markdown", caption="Dependencia categórica sol. 4 conglomerados, por pares de categorías en Sexo (corrección Holm-Bonferroni)")
Dependencia categórica sol. 4 conglomerados, por pares de categorías en Sexo (corrección Holm-Bonferroni)
n group1 group2 statistic p df p.adj p.adj.signif
5998 6623, Un trimestre, TSM(4) 6612, Un trimestre, TUS(3) 210.6916556 0.000 1 <0.001 ****
5647 6623, Un trimestre, TSM(4) 6522, Un semestre TSM(1) 0.2321740 0.630 1 1.000 ns
5477 6623, Un trimestre, TSM(4) 6574, Comorbilidad un trimestre(2) 68.2131632 0.000 1 <0.001 ****
1149 6612, Un trimestre, TUS(3) 6522, Un semestre TSM(1) 93.3484745 0.000 1 <0.001 ****
979 6612, Un trimestre, TUS(3) 6574, Comorbilidad un trimestre(2) 0.0028565 0.957 1 1.000 ns
628 6522, Un semestre TSM(1) 6574, Comorbilidad un trimestre(2) 48.2841261 0.000 1 <0.001 ****

Tiempo que demora esta sección: 0 minutos

1.1.3.g. Comparación covariables- Edad
Código
dt_ing_calendar_quarter_t_desde_primera_adm_dedup |>
    dplyr::filter(quarter == 0) |>
    dplyr::inner_join(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens[,c("run","clus_pam_om4")], by="run") |>
    dplyr::group_by(clus_pam_om4) |>
    dplyr::summarise(mean_edad = mean(min_edad_anos),
                     sd= sd(min_edad_anos),
                     p50= quantile(min_edad_anos,.5),
                     p25 = quantile(min_edad_anos, 0.25),
                     p75 = quantile(min_edad_anos, 0.75)) |>
    dplyr::mutate(sum= paste0(sprintf("%1.2f",mean_edad), " ± ", sprintf("%1.2f",sd), " ; ",p50," [",p25,", ",p75,"]"))|> 
    select(clus_pam_om4, sum)|>
   (\(df) {
     if (interactive()) {mutate(df, across(-clus_pam_om4, ~gsub("\\.", ",", .)))|> rio::export("clipboard")}
     knitr::kable(df, caption="Descriptivos, edad minima de ingreso por conglomerado", digits=2)
  })()
Descriptivos, edad minima de ingreso por conglomerado
clus_pam_om4 sum
6623, Un trimestre, TSM(4) 20.58 ± 4.32 ; 20 [17, 24]
6612, Un trimestre, TUS(3) 22.41 ± 4.30 ; 23 [19, 26]
6522, Un semestre TSM(1) 19.88 ± 4.28 ; 19 [16, 23]
6574, Comorbilidad un trimestre(2) 21.78 ± 4.21 ; 21 [18, 25]

Tiempo que demora esta sección: 0 minutos

Código
 dt_ing_calendar_quarter_t_desde_primera_adm_dedup|> 
  filter(quarter == 0)|> 
  inner_join(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens[, c("run", "clus_pam_om4")],
             by = "run")|>
  dplyr::mutate(clus_pam_om4= str_wrap(clus_pam_om4, width = 20))|> 
  group_by(clus_pam_om4)|> 
  dplyr::summarise(mean_edad = mean(min_edad_anos),
            sd_edad   = sd(min_edad_anos),
            n         = n())|> 
  dplyr::mutate(sem         = sd_edad / sqrt(n),
         error_lower = mean_edad - sem,
         error_upper = mean_edad + sem)|> 
  ggplot(aes(x = clus_pam_om4, y = mean_edad)) +
  geom_point(color = "black", size = 3) +
  geom_errorbar(aes(ymin = error_lower, ymax = error_upper), width = 0.2, color = "black") +
  labs(x = "Conglomerado (k = 4)", y = "Edad al primer evento 2018 promedio") +
  theme_minimal() +
  coord_flip() +
  theme(axis.text.y = element_text(size = 17 * .7, face = "bold"),
        axis.text.x = element_text(size = 17 * .7, face = "bold", lineheight = 0.9),
        axis.title.x = element_text(size = 16 * .7, face = "bold"),
        axis.title.y = element_text(size = 16 * .7, face = "bold"),
        plot.margin = unit(c(0.5, 0.5, 0.5, 0.5), "cm"))

ggsave("_figs/edad_minima_por_cluster_pam_om4_q_25.png", width=8, height=5, dpi=600)
Edad promedio primer ingreso con errores estándar por conglomerado

Edad promedio primer ingreso con errores estándar por conglomerado

Tiempo que demora esta sección: 0 minutos

Código
invisible("Prueba de Levene par igualdad de varianzas")
with(dt_ing_calendar_quarter_t_desde_primera_adm_dedup |>
               dplyr::filter(quarter == 0) |>
               dplyr::inner_join(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens[,c("run","clus_pam_om4")], by="run"), car::leveneTest(min_edad_anos, clus_pam_om4))
#NS
anova_clus_pam_om4_q <- oneway.test(min_edad_anos ~ clus_pam_om4, 
             data = dt_ing_calendar_quarter_t_desde_primera_adm_dedup |>
               dplyr::filter(quarter == 0) |>
               dplyr::inner_join(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens[,c("run","clus_pam_om4")], by="run"),var.equal = T)

with(dt_ing_calendar_quarter_t_desde_primera_adm_dedup |>
               dplyr::filter(quarter == 0) |>
               dplyr::inner_join(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens[,c("run","clus_pam_om4")], by="run"), oneway_anova_effect_size (min_edad_anos, clus_pam_om4))

# Ver los resultados del ANOVA
print(anova_clus_pam_om4_q)
#F = 49.148, num df = 3, denom df = 6622, p-value < 2.2e-16
#$eta_squared
#[1] 0.0217808


message("Descartando valores negativos en sil width")
with(dt_ing_calendar_quarter_t_desde_primera_adm_dedup |>
    dplyr::filter(quarter == 0) |>
    dplyr::inner_join(subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, !rn %in% sil_neg_pam_om_clus4_q)[,c("run","clus_pam_om4")], by="run"), 
     oneway.test(min_edad_anos ~ clus_pam_om4,var.equal = T)
     )
#F = 48.252, num df = 3, denom df = 6469, p-value < 2.2e-16
Levene's Test for Homogeneity of Variance (center = median)
        Df F value Pr(>F)
group    3  0.4775  0.698
      6622               
$anova_summary
              Df Sum Sq Mean Sq F value Pr(>F)    
group          3   2746   915.4   49.15 <2e-16 ***
Residuals   6622 123343    18.6                   
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

$eta_squared
[1] 0.0217808


    One-way analysis of means

data:  min_edad_anos and clus_pam_om4
F = 49.148, num df = 3, denom df = 6622, p-value < 2.2e-16


    One-way analysis of means

data:  min_edad_anos and clus_pam_om4
F = 48.252, num df = 3, denom df = 6469, p-value < 2.2e-16

Tiempo que demora esta sección: 0 minutos

Código
rstatix::games_howell_test(min_edad_anos ~ clus_pam_om4, 
  data =dt_ing_calendar_quarter_t_desde_primera_adm_dedup |>
               dplyr::filter(quarter == 0) |>
               dplyr::inner_join(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens[,c("run","clus_pam_om4")], by="run")) |> 
    dplyr::select(-1) |> 
    dplyr::mutate(
    summary = sprintf(
      "%.2f [%.2f, %.2f], p= %s",
      as.numeric(estimate), 
      as.numeric(conf.low), 
      as.numeric(conf.high), 
      ifelse(p.adj < 0.001, "<0.001", sprintf("%.3f", p.adj)))) |> 
  dplyr::select(!any_of(c("estimate","conf.low", "conf.high", "p.adj", "p.adj.signif"))) |> 
  knitr::kable("markdown", col.names=c("Conglomerado1","Conglomerado2", "Estimación"), caption="Post-hoc, conglomerado vs. Promedio días de tratamiento")


message("Descartando valores negativos en sil width")
sens_min_anios_clus_pam_om4_q<-
rstatix::games_howell_test(min_edad_anos ~ clus_pam_om4,data = dt_ing_calendar_quarter_t_desde_primera_adm_dedup |>
    dplyr::filter(quarter == 0) |>
    dplyr::inner_join(subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, !rn %in% sil_neg_pam_om_clus4_q)[,c("run","clus_pam_om4")], by="run")
     ) # dplyr::mutate(sens_min_anios_clus_pam_om4_q , group1 = gsub(",.*", "", group1), group2 = gsub(",.*", "", group2))
#   .y.           group1 group2 estimate conf.low conf.high    p.adj p.adj.signif
#   <chr>         <chr>  <chr>     <dbl>    <dbl>     <dbl>    <dbl> <chr>       
# 1 min_edad_anos 6623   6612      1.83     1.39      2.26  1.19e-13 ****        
# 2 min_edad_anos 6623   6522     -0.863   -1.58     -0.149 1.1 e- 2 *           
# 3 min_edad_anos 6623   6574      1.20     0.461     1.93  2.13e- 4 ***         
# 4 min_edad_anos 6612   6522     -2.69    -3.49     -1.88  0        ****        
# 5 min_edad_anos 6612   6574     -0.629   -1.45      0.196 2.02e- 1 ns          
# 6 min_edad_anos 6522   6574      2.06     1.06      3.06  9.87e- 7 ****  
Post-hoc, conglomerado vs. Promedio días de tratamiento
Conglomerado1 Conglomerado2 Estimación
6623, Un trimestre, TSM(4) 6612, Un trimestre, TUS(3) 1.83 [1.39, 2.26], p= <0.001
6623, Un trimestre, TSM(4) 6522, Un semestre TSM(1) -0.71 [-1.28, -0.13], p= 0.009
6623, Un trimestre, TSM(4) 6574, Comorbilidad un trimestre(2) 1.20 [0.46, 1.93], p= <0.001
6612, Un trimestre, TUS(3) 6522, Un semestre TSM(1) -2.53 [-3.21, -1.85], p= <0.001
6612, Un trimestre, TUS(3) 6574, Comorbilidad un trimestre(2) -0.63 [-1.45, 0.20], p= 0.202
6522, Un semestre TSM(1) 6574, Comorbilidad un trimestre(2) 1.90 [1.00, 2.81], p= <0.001

Tiempo que demora esta sección: 0 minutos

1.1.3.h. Comparación covariables- Previsión
Código
tab_clus_prev_pam_om4_q<-
ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens |>
    janitor::tabyl(prev_benef_rec_post, clus_pam_om4)

tab_clus_prev_pam_om4_q|> 
   (\(df) {
     print(janitor::chisq.test(df))
     print(janitor::fisher.test(df, simulate.p.value = T, B = 1e5))
  })()
#X-squared = 30.37, df = 12, p-value = 0.002456
#p-value = 0.00143 FIsher


cat("Sin FFAA")
tab_clus_prev_pam_om4_q[2:5,]|> 
   (\(df) {
     print(janitor::chisq.test(df))
     print(janitor::fisher.test(df, simulate.p.value = T, B = 1e5))
  })()

tab_clus_prev_pam_om4_q|> 
  janitor::adorn_percentages("col") |> 
  janitor::adorn_rounding(digits = 3) |> 
  dplyr::mutate(across(-prev_benef_rec_post, ~sprintf("%d (%.1f%%)", tab_clus_prev_pam_om4_q[[cur_column()]],.*100))) |> 
  #dplyr::mutate_at(2:ncol(.),~scales::percent(.)) |> 
  mutate(prev_benef_rec_post = factor(prev_benef_rec_post, levels = c("ISAPRE", "FONASA D", "FONASA BC", "FONASA A", "FFAA")))|> 
  arrange(prev_benef_rec_post)|>
  (\(df) {
  if (interactive()) {mutate(df, across(-prev_benef_rec_post, ~ gsub("%", "", gsub("\\.", ",", .))))|> rio::export("clipboard")}
  knitr::kable(df, caption="Porcentajes por columna, conglomerado vs. Previsión")
  })()

    Pearson's Chi-squared test

data:  df
X-squared = 30.37, df = 12, p-value = 0.002456


    Fisher's Exact Test for Count Data with simulated p-value (based on
    1e+05 replicates)

data:  df
p-value = 0.00129
alternative hypothesis: two.sided

Sin FFAA
    Pearson's Chi-squared test

data:  df
X-squared = 14.815, df = 9, p-value = 0.09614


    Fisher's Exact Test for Count Data with simulated p-value (based on
    1e+05 replicates)

data:  df
p-value = 0.09389
alternative hypothesis: two.sided
Porcentajes por columna, conglomerado vs. Previsión
prev_benef_rec_post 6623, Un trimestre, TSM(4) 6612, Un trimestre, TUS(3) 6522, Un semestre TSM(1) 6574, Comorbilidad un trimestre(2)
ISAPRE 1357 (25.9%) 169 (22.5%) 95 (23.8%) 47 (20.5%)
FONASA D 601 (11.5%) 104 (13.9%) 44 (11.0%) 29 (12.7%)
FONASA BC 1692 (32.2%) 242 (32.3%) 128 (32.1%) 88 (38.4%)
FONASA A 1378 (26.3%) 222 (29.6%) 119 (29.8%) 62 (27.1%)
FFAA 220 (4.2%) 13 (1.7%) 13 (3.3%) 3 (1.3%)

Tiempo que demora esta sección: 0 minutos

Código
chisq_cramerv(tab_clus_prev_pam_om4_q[,-1])
# $chisq_statistic
# [1] "30.37"
# 
# $chisq_df
# df 
# 12 
# 
# $chisq_p_value
# [1] "0.0025"
# 
# $cramers_v
# [1] "0.04"

# 
fisher.test(with(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, table(prev_benef_rec_post, clus_pam_om4)), simulate.p.value = T, B=1e5)
#p-value = 0.00133

message("Descartando valores negativos en sil width")
chisq_cramerv(with(subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, !rn %in% sil_neg_pam_om_clus4_q), table(prev_benef_rec_post, clus_pam_om4)))
# $chisq_statistic
# [1] "30.73"
# 
# $chisq_df
# df 
# 12 
# 
# $chisq_p_value
# [1] "0.0022"
# 
# $cramers_v
# [1] "0.04"

fisher.test(with(subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, !rn %in% sil_neg_pam_om_clus4_q), table(prev_benef_rec_post, clus_pam_om4)), simulate.p.value = T, B=1e5)
#p-value = 0.00117


cat("Para post-hoc convendría consultar https://adaptivedesignstrial.shinyapps.io/posthoc/")

chisq.posthoc.test(tab_clus_prev_pam_om4_q[,-1])|>
  (\(df) dplyr::mutate(df, across(3:ncol(df), ~round(as.numeric(gsub("\\*","",.x)),3))))()|>
  # knitr::kable("html", caption="Comparación post-hoc, conglomerado-región") |>
  dplyr::group_by(Dimension)|>
  (\(df) dplyr::summarise(df, across(2:(ncol(df)-1), ~paste0(first(sprintf("%1.2f", .x)), " (p=", last(sprintf("%1.3f", .x)), ")"))))()|>
  (\(df) dplyr::mutate(df, across(2:length(names(df)), ~gsub("p=0.000)", "p<0.001)", .x))))()|> 
  dplyr::mutate(Dimension = dplyr::pull(tab_clus_prev_pam_om4_q[1]))|>
mutate(Dimension = factor(Dimension, levels = c("ISAPRE", "FONASA D", "FONASA BC", "FONASA A", "FFAA")))|> 
  arrange(Dimension)|>
  (\(df) {
  if (interactive()) {mutate(df, across(-Dimension, ~ gsub("\\(|\\)", "", gsub("\\.", ",", .))))|> rio::export("clipboard")}
  knitr::kable(df, caption="Comparación post-hoc, conglomerado-previsión")
  })()

pairwise_chisq_gof_test(tab_clus_prev_pam_om4_q[-1], p.adjust.method="holm")|> 
    knitr::kable("markdown", caption="Dependencia categórica sol. 4 conglomerados, por pares de categorías en Previsión (corrección Holm-Bonferroni)")
$chisq_statistic
[1] "30.37"

$chisq_df
df 
12 

$chisq_p_value
[1] "0.0025"

$cramers_v
[1] "0.04"


    Fisher's Exact Test for Count Data with simulated p-value (based on
    1e+05 replicates)

data:  with(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, table(prev_benef_rec_post, clus_pam_om4))
p-value = 0.00135
alternative hypothesis: two.sided

$chisq_statistic
[1] "30.73"

$chisq_df
df 
12 

$chisq_p_value
[1] "0.0022"

$cramers_v
[1] "0.04"


    Fisher's Exact Test for Count Data with simulated p-value (based on
    1e+05 replicates)

data:  with(subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, !rn %in% sil_neg_pam_om_clus4_q), table(prev_benef_rec_post, clus_pam_om4))
p-value = 0.00119
alternative hypothesis: two.sided

Para post-hoc convendría consultar https://adaptivedesignstrial.shinyapps.io/posthoc/
Comparación post-hoc, conglomerado-previsión
Dimension 6623, Un trimestre, TSM(4) 6612, Un trimestre, TUS(3) 6522, Un semestre TSM(1) 6574, Comorbilidad un trimestre(2)
ISAPRE 2.50 (p=0.246) -1.77 (p=1.000) -0.65 (p=1.000) -1.65 (p=1.000)
FONASA D -1.43 (p=1.000) 1.92 (p=1.000) -0.46 (p=1.000) 0.44 (p=1.000)
FONASA BC -0.70 (p=1.000) -0.11 (p=1.000) -0.16 (p=1.000) 1.97 (p=0.983)
FONASA A -2.23 (p=0.520) 1.78 (p=1.000) 1.37 (p=1.000) 0.07 (p=1.000)
FFAA 3.63 (p=0.006) -3.10 (p=0.039) -0.54 (p=1.000) -1.98 (p=0.949)
Dependencia categórica sol. 4 conglomerados, por pares de categorías en Previsión (corrección Holm-Bonferroni)
n group1 group2 statistic p df p.adj p.adj.signif
5998 6623, Un trimestre, TSM(4) 6612, Un trimestre, TUS(3) 19.065997 0.000763 4 0.00458 **
5647 6623, Un trimestre, TSM(4) 6522, Un semestre TSM(1) 3.229797 0.520000 4 1.00000 ns
5477 6623, Un trimestre, TSM(4) 6574, Comorbilidad un trimestre(2) 9.831513 0.043400 4 0.21700 ns
1149 6612, Un trimestre, TUS(3) 6522, Un semestre TSM(1) 4.497691 0.343000 4 1.00000 ns
979 6612, Un trimestre, TUS(3) 6574, Comorbilidad un trimestre(2) 3.061735 0.548000 4 1.00000 ns
628 6522, Un semestre TSM(1) 6574, Comorbilidad un trimestre(2) 5.283271 0.259000 4 1.00000 ns

Tiempo que demora esta sección: 0 minutos

1.1.3.i. Comparación covariables- Niv. Complejidad
Código
tab_clus_compl_pam_om4_q<-
ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens |> 
  dplyr::inner_join(data_long_establecimiento_2024_std[,c("ESTAB_HOMO", "codigo_region", "nivel_de_atencion", "nivel_de_complejidad")], 
                    by = c("estab_homo_base" = "ESTAB_HOMO"), multiple = "first") |> 
  janitor::tabyl(nivel_de_complejidad, clus_pam_om4) 

tab_clus_compl_pam_om4_q|> 
  janitor::adorn_percentages("col")|> 
  janitor::adorn_rounding(digits = 3)|> 
   dplyr::mutate(across(-nivel_de_complejidad, ~sprintf("%d (%.1f%%)", tab_clus_compl_pam_om4_q[[cur_column()]],.*100)))|> 
  mutate(nivel_de_complejidad = factor(nivel_de_complejidad, levels = c("Alta Complejidad", "Mediana Complejidad", "Baja Complejidad", "Pendiente", "Sin dato")))|> 
  arrange(nivel_de_complejidad)|>
  (\(df) {
  if (interactive()) {mutate(df, across(-nivel_de_complejidad, ~ gsub("%", "", gsub("\\.", ",", .))))|> rio::export("clipboard")}
  knitr::kable(df, caption="Tabla de contingencia, Niv. de complejidad (proporción por columna)")
  })()
Tabla de contingencia, Niv. de complejidad (proporción por columna)
nivel_de_complejidad 6623, Un trimestre, TSM(4) 6612, Un trimestre, TUS(3) 6522, Un semestre TSM(1) 6574, Comorbilidad un trimestre(2)
Alta Complejidad 3203 (61.0%) 509 (67.9%) 203 (50.9%) 168 (73.4%)
Mediana Complejidad 1027 (19.6%) 86 (11.5%) 101 (25.3%) 39 (17.0%)
Baja Complejidad 849 (16.2%) 143 (19.1%) 70 (17.5%) 20 (8.7%)
Pendiente 133 (2.5%) 5 (0.7%) 20 (5.0%) 2 (0.9%)
Sin dato 36 (0.7%) 7 (0.9%) 5 (1.3%) 0 (0.0%)

Tiempo que demora esta sección: 0 minutos

Código
tab_clus_compl_pam_om4_q |> 
  janitor::fisher.test(simulate.p.value=T, B=1e5)
#p-value = 1e-05


chisq_cramerv(tab_clus_compl_pam_om4_q[,-1])
# $chisq_statistic
# [1] "88.83"
# 
# $chisq_df
# df 
# 12 
# 
# $chisq_p_value
# [1] "<0.001"
# 
# $cramers_v
# [1] "0.07"

message("Descartando valores negativos en sil width")
chisq_cramerv(with(subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, !rn %in% sil_neg_pam_om_clus4_q) |> 
  dplyr::inner_join(data_long_establecimiento_2024_std[,c("ESTAB_HOMO", "codigo_region", "nivel_de_atencion", "nivel_de_complejidad")], 
  by = c("estab_homo_base" = "ESTAB_HOMO"), multiple = "first"), table(nivel_de_complejidad, clus_pam_om4)))
# $chisq_statistic
# [1] "72.99"
# 
# $chisq_df
# df 
# 12 
# 
# $chisq_p_value
# [1] "<0.001"
# 
# $cramers_v
# [1] "0.06"

fisher.test(with(subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, !rn %in% sil_neg_pam_om_clus4_q) |> 
  dplyr::inner_join(data_long_establecimiento_2024_std[,c("ESTAB_HOMO", "codigo_region", "nivel_de_atencion", "nivel_de_complejidad")], by = c("estab_homo_base" = "ESTAB_HOMO"), multiple = "first"), table(nivel_de_complejidad, clus_pam_om4)), simulate.p.value = T, B=1e5)
#p-value = 1e-05

cat("Para post-hoc convendría consultar https://adaptivedesignstrial.shinyapps.io/posthoc/")

chisq.posthoc.test(tab_clus_compl_pam_om4_q[-1])|> 
  (\(df) dplyr::mutate(df, across(3:ncol(df), ~round(as.numeric(gsub("\\*","",.x)),3))))()|>
  # knitr::kable("html", caption="Comparación post-hoc, conglomerado-región") |>
  (\(df) dplyr::group_by(df, Dimension))()|>
  (\(df) dplyr::summarise(df, across(2:(ncol(df) - 1), ~paste0(first(sprintf("%1.2f", .x)), " (p=", last(sprintf("%1.3f", .x)), ")"))))()|>
  (\(df) dplyr::mutate(df, across(2:length(names(df)), ~gsub("p=0.000)", "p<0.001)",.x))))()|>
  ungroup()|> 
  dplyr::mutate(Dimension = dplyr::pull(tab_clus_compl_pam_om4_q[1]))|>
  mutate(Dimension = factor(Dimension, levels = c("Alta Complejidad", "Mediana Complejidad", "Baja Complejidad", "Pendiente", "Sin dato")))|> 
  arrange(Dimension)|>
  (\(df) {
    if (interactive()) {mutate(df, across(-Dimension, ~ gsub("\\(|\\)", "", gsub("\\.", ",", .))))|> rio::export("clipboard")}
    knitr::kable(df, "markdown", caption="Comparación post-hoc, conglomerado-Niv. complejidad")
  })() 
  
pairwise_chisq_gof_test(tab_clus_compl_pam_om4_q[-1], p.adjust.method="holm")|> 
    knitr::kable("markdown", caption="Dependencia categórica sol. 4 conglomerados, por pares de categorías en Niv. Complejidad (corrección Holm-Bonferroni)")

    Fisher's Exact Test for Count Data with simulated p-value (based on
    1e+05 replicates)

data:  tab_clus_compl_pam_om4_q
p-value = 1e-05
alternative hypothesis: two.sided

$chisq_statistic
[1] "88.83"

$chisq_df
df 
12 

$chisq_p_value
[1] "<0.001"

$cramers_v
[1] "0.07"

$chisq_statistic
[1] "72.99"

$chisq_df
df 
12 

$chisq_p_value
[1] "<0.001"

$cramers_v
[1] "0.06"


    Fisher's Exact Test for Count Data with simulated p-value (based on
    1e+05 replicates)

data:  with(dplyr::inner_join(subset(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens, !rn %in% sil_neg_pam_om_clus4_q), data_long_establecimiento_2024_std[, c("ESTAB_HOMO", "codigo_region", "nivel_de_atencion", "nivel_de_complejidad")], by = c(estab_homo_base = "ESTAB_HOMO"), multiple = "first"), table(nivel_de_complejidad, clus_pam_om4))
p-value = 1e-05
alternative hypothesis: two.sided

Para post-hoc convendría consultar https://adaptivedesignstrial.shinyapps.io/posthoc/
Comparación post-hoc, conglomerado-Niv. complejidad
Dimension 6623, Un trimestre, TSM(4) 6612, Un trimestre, TUS(3) 6522, Un semestre TSM(1) 6574, Comorbilidad un trimestre(2)
Alta Complejidad -1.92 (p=1.000) 3.73 (p=0.004) -4.55 (p<0.001) 3.72 (p=0.004)
Mediana Complejidad 2.67 (p=0.150) -5.53 (p<0.001) 3.37 (p=0.015) -0.74 (p=1.000)
Baja Complejidad -0.65 (p=1.000) 2.15 (p=0.626) 0.68 (p=1.000) -3.16 (p=0.031)
Pendiente 1.24 (p=1.000) -3.31 (p=0.018) 3.49 (p=0.010) -1.55 (p=1.000)
Sin dato -0.72 (p=1.000) 0.72 (p=1.000) 1.28 (p=1.000) -1.32 (p=1.000)
Dependencia categórica sol. 4 conglomerados, por pares de categorías en Niv. Complejidad (corrección Holm-Bonferroni)
n group1 group2 statistic p df p.adj p.adj.signif
5998 6623, Un trimestre, TSM(4) 6612, Un trimestre, TUS(3) 41.99007 0.00e+00 4 1.00e-07 ****
5647 6623, Un trimestre, TSM(4) 6522, Un semestre TSM(1) 22.93875 1.30e-04 4 3.90e-04 ***
5477 6623, Un trimestre, TSM(4) 6574, Comorbilidad un trimestre(2) 17.83641 1.33e-03 4 1.96e-03 **
1149 6612, Un trimestre, TUS(3) 6522, Un semestre TSM(1) 66.00124 0.00e+00 4 0.00e+00 ****
979 6612, Un trimestre, TUS(3) 6574, Comorbilidad un trimestre(2) 18.51223 9.80e-04 4 1.96e-03 **
628 6522, Un semestre TSM(1) 6574, Comorbilidad un trimestre(2) 34.79469 5.00e-07 4 2.00e-06 ****

Tiempo que demora esta sección: 0 minutos

1.1.4. Compilación comparación covariables

Código
# Definir los datos correctamente
data_pam_om4_q <-cbind.data.frame(
  Grupo= c("6035,\nUn trimestre,\nTSM(4)", 
             "6025,\nUn trimestre,\nTUS(3)", 
             "5939,\nUn semestre\nTSM(1)", 
             "5989,\nComorbilidad un\ntrimestre(2)"), 
      PPOO_bin            = c(NA, NA, NA, NA), 
      PPOO_sinautoid          = c(NA, NA, NA, NA), 
      PPOO_conautoid          = c(NA, NA, NA, NA), 
      Mortalidad              = c(NA, NA, NA, NA), 
      RM                      = c(NA, "-", NA, "+"), 
      `Macrozona-Austral`       = c(NA, NA, NA, NA), 
      `Macrozona-Centro`        = c(NA, NA, NA, NA), 
      `Macrozona-Centro Sur`    = c(NA, NA, NA, NA), 
      `Macrozona-Norte`        = c("+","-", NA, NA), 
      `Macrozona-Sur`         = c(NA, "+", NA, NA), 
      Sexo_mujeres             = c(NA, "-", NA, "-"), 
      `Edad ingreso`         = c("-", "+", "-", "+"), 
      `Previsión-FFAA`         = c("+", "-", NA, NA), 
      `Previsión-FONASA A`     = c(NA, NA, NA, NA), 
      `Previsión-FONASA BC`     = c(NA, NA, NA, NA), 
      `Previsión-FONASA D`     = c(NA, NA, NA, NA), 
      `Previsión-ISAPRE`     = c(NA, NA, NA, NA), 
      `NivComp-Baja`     = c(NA, NA, NA, NA), 
      `NivComp-Media`     = c(NA, "-", NA, NA), 
      `NivComp-Alta`     = c(NA, "+", "-", "+"))
#
# Asegurar que los nombres de las columnas sean válidos y no haya espacios en blanco
# Derretir el dataframe para que sea adecuado para ggplot2
data_melt_pam_om4_q <- reshape2::melt(data_pam_om4_q, id.vars = 'Grupo', variable.name = 'Variable', value.name = 'Asociación')

# Reemplazar los NA por un valor vacío
data_melt_pam_om4_q$Asociación[is.na(data_melt_pam_om4_q$Asociación)] <- "\n"

# Crear el gráfico con ggplot
plot_data_melt_pam_om4_q<-
data_melt_pam_om4_q |> 
  dplyr::mutate(Variable = gsub("_", " ", Variable)) |> 
ggplot(aes(x = Variable, y = Grupo, fill = Asociación)) +
  geom_tile(color = "white", size = 0.8) +
  scale_fill_manual(values = c("+" = "#556B2F", "-" = "#E2725B", "\n" = "white")) +
  labs(title =NULL, x = "Variables", y = "Conglomerado") +
  theme_minimal() +
  theme(#axis.text.x = element_text(angle = 45, hjust = 1),
        panel.grid = element_blank())+
  theme(
    axis.text.y = element_text(size = 17*.7, face = "bold"),#,margin = margin(l = 7)),           # Tamaño de las etiquetas de los grupos étnicos
    axis.text.x = element_text(size = 17*.7, face = "bold"),           # Tamaño de las etiquetas del eje X
    axis.title.x = element_text(size = 16*.7, face = "bold"),#,margin = margin(t = -15)),          # Tamaño del título del eje X
    axis.title.y = element_text(size = 16*.7, face = "bold"),          # Tamaño del título del eje Y
    plot.title = NULL,  # Tamaño y estilo del título del gráfico
    legend.title = element_text(size = 17*.7, face = "bold"),          # Tamaño del título de la leyenda
    legend.spacing.y = unit(1.2, "lines"),
    legend.box.spacing = unit(0.5, "lines"),      # Controla el espacio entre la leyenda y el gráfico
    legend.margin = margin(5, 5, 5, 5),  
    legend.key.height = unit(1, "cm"),  
    legend.text = element_text(size = 15*.7, face = "bold")            # Tamaño del texto de la leyenda
  ) +
  coord_flip()

plot_data_melt_pam_om4_q

ggsave(filename= "_figs/asociaciones_pam_om4_q_25.png", plot_data_melt_pam_om4_q, width=11*.8, height=6*.8, dpi=600)
Comparación covariables con agrupamiento

Comparación covariables con agrupamiento

Tiempo que demora esta sección: 0 minutos

Comparación con base original PPOO

Seleccionamos casos de 2018 en adelante para hacer una base comparable.

Código
data_nueva<- rio::import("_data/EH_2010_2022_Pasantes_v2_encrip.csv")
# 2) Opción: cargar tidytable DESPUÉS de dplyr para "sobreponer" sus verbs
library(dplyr)
library(stringr)
library(janitor)
library(tidytable)  # cargar después


cat("Tramos un criterio inclusivo que incluya cualquier registro en la que las personas han reportado pertenencia a PPOO en MINSAL, RSH o CONADI")
ppoo_inclusivo<- rio::import("filtered_df.csv.gz", skip=1)

#table(data_nueva$GLOSA_PUEBLO_ORIGINARIO) |> data.frame()
#                       Var1     Freq
# 1                            115413
# 2                   AYMARA    22317
# 3                    COLLA     1778
# 4                 DIAGUITA    19814
# 5                 KAWÉSQAR    14679
# 6  LICAN ANTAI (ATACAMEÑO)     4414
# 7                  MAPUCHE   306359
# 8                  NINGUNO 19061628
# 9       OTRO (ESPECIFICAR)  1398382
# 10                 QUECHUA     2189
# 11    RAPA NUI (PASCUENSE)     6802
# 12          YAGÁN (YÁMANA)     3229


regex_otro <- "AYMARA|COLLA|DIAGUITA|KAWÉSQAR|RAPA NUI|YAGÁN|OTRO|LICAN|QUECHUA|OTRO"

tab_clas_por_run <- 
  data_nueva|> 
  filter(FECHA_INGRESO_FMT_DEIS >= as.Date("2018-01-01"), FECHA_INGRESO_FMT_DEIS < as.Date("2019-01-01"))|> 
    replace_na(list(
    CyA_Conadi = 0,
    CI_Conadi  = 0,
    RSH        = 0
  ))|> 
  arrange(RUN, FECHA_INGRESO_FMT_DEIS)|> 
  group_by(RUN) |> 
  slice(1) |> 
  ungroup() |> 
   mutate(
    glosa_pueblo_originario_rec = case_when(
      GLOSA_PUEBLO_ORIGINARIO == "NINGUNO" &
        (CyA_Conadi == 1 | CI_Conadi == 1 | RSH == 1 )~ "DESCONOCIDO",
      GLOSA_PUEBLO_ORIGINARIO == "NINGUNO" &
        RUN %in% ppoo_inclusivo[,2]~ "DESCONOCIDO",
      T~ as.character(GLOSA_PUEBLO_ORIGINARIO)   # evita choque factor/chr
    )
  )|> 
  summarise(
    tiene_otro_po     = any(str_detect(glosa_pueblo_originario_rec, regex_otro)),
    tiene_mapuche     = any(str_detect(glosa_pueblo_originario_rec, "MAPUCHE")),
    tiene_ninguno     = any(glosa_pueblo_originario_rec == "NINGUNO"),
    tiene_desconocido = any(glosa_pueblo_originario_rec == "DESCONOCIDO"), # si dejo al final, no recojo ningun "DESCONOCIDO"    
    .by = RUN)#|>

cat("ID345: Clasificación PPOO reportado en 2018, criterio inclusivo para desconocido\n")

tab_clas_por_run|>                       # tu data frame
  mutate(
    clas_por_run = case_when(
      # 1. priorizamos Mapuche
      tiene_mapuche ~ "Mapuche",
      # 2. luego otros pueblos originarios distintos de Mapuche
      tiene_otro_po ~ "Otros reportados (no mapuche)",
      # 3. si no hay Mapuche ni otros y se reporta “desconocido”
      tiene_desconocido ~ "Desconocido",
      # 4. si no hay Mapuche ni otros y se reporta “ninguno”
      !tiene_mapuche & !tiene_otro_po & tiene_ninguno ~ "Ninguno puro",
      # 4. cualquier otro caso ⇒ NA
      TRUE ~ NA_character_
    )
  ) |> 
  tabyl(clas_por_run, show_na = TRUE) |> 
   mutate(percent=round(percent*100, 1)) |> mutate(clas_por_run= factor(clas_por_run, levels= c("Ninguno puro", "Desconocido", "Otros reportados (no mapuche)", "Mapuche")))|> 
    arrange(clas_por_run)|>
    (\(df) {
      if (interactive()) {df|> rio::export("clipboard")}
      knitr::kable(df, caption="Porcentajes por columna, conglomerado vs. PPOO")
    })()
  
# clas_por_run                  |         n| percent|
# |:-----------------------------|---------:|-------:|
# |Ninguno puro                  | 106406500|    83.3|
# |Desconocido                   |  18801300|    14.7|
# |Otros reportados (no mapuche) |    417000|     0.3|
# |Mapuche                       |   2055500|     1.6|
Tramos un criterio inclusivo que incluya cualquier registro en la que las personas han reportado pertenencia a PPOO en MINSAL, RSH o CONADIID345: Clasificación PPOO reportado en 2018, criterio inclusivo para desconocido
Porcentajes por columna, conglomerado vs. PPOO
clas_por_run n percent
Ninguno puro 1064065 83.3
Desconocido 190608 14.9
Otros reportados (no mapuche) 3729 0.3
Mapuche 18401 1.4

Tiempo que demora esta sección: 0 minutos

Comparamos contando eventos durante el 2018, luego vemos las clasificaciones durante el 2018 en términos generales (sin haber filtrado por causas). También lo comparamos después por las clasificaciones con el primer evento de 2018 por SM/TUS. Eso si, ahora ya no usamos un criterio inclusivo para clasificar, sino sólo registros de MIDESO (no los históricos de MINSAL).

Código
cat("Aquí ya no se clasifica como Desconocido si hay información en MINSAL sobre autoidentificación, sino solo MIDESO")

tab_clas_por_run2 <- 
  data_nueva|> 
  filter(FECHA_INGRESO_FMT_DEIS >= as.Date("2018-01-01"), FECHA_INGRESO_FMT_DEIS < as.Date("2019-01-01"))|> 
    replace_na(list(
    CyA_Conadi = 0,
    CI_Conadi  = 0,
    RSH        = 0
  ))|> 
   mutate(
    glosa_pueblo_originario_rec = case_when(
      GLOSA_PUEBLO_ORIGINARIO == "NINGUNO" &
      (CyA_Conadi == 1 | CI_Conadi == 1 | RSH == 1)~ "DESCONOCIDO",
      # GLOSA_PUEBLO_ORIGINARIO == "NINGUNO" &
      # RUN %in% ppoo_inclusivo[,2]~ "DESCONOCIDO",#esto es porque en alguna oportunidad registro pertenencia 
      T~ as.character(GLOSA_PUEBLO_ORIGINARIO)   # evita choque factor/chr
    )
  )|> 
  summarise(
    tiene_otro_po     = any(str_detect(glosa_pueblo_originario_rec, regex_otro)),
    tiene_mapuche     = any(str_detect(glosa_pueblo_originario_rec, "MAPUCHE")),
    tiene_ninguno     = any(glosa_pueblo_originario_rec == "NINGUNO"),
    tiene_desconocido = any(glosa_pueblo_originario_rec == "DESCONOCIDO"), # si dejo al final, no recojo ningun "DESCONOCIDO"    
    .by = RUN)#|>
tab_clas_por_run2|>                       # tu data frame
  mutate(
    clas_por_run = case_when(
      # 1. priorizamos Mapuche
      tiene_mapuche ~ "Mapuche",
      # 2. luego otros pueblos originarios distintos de Mapuche
      tiene_otro_po ~ "Otros reportados (no mapuche)",
      # 3. si no hay Mapuche ni otros y se reporta “ninguno”
      tiene_desconocido ~ "Desconocido",
      # 4. si no hay Mapuche ni otros y se reporta “ninguno”
      !tiene_mapuche & !tiene_otro_po & tiene_ninguno ~ "Ninguno puro",
      # 4. cualquier otro caso ⇒ NA
      TRUE ~ NA_character_
    )
  )|> 
  janitor::tabyl(clas_por_run, show_na = TRUE)|>mutate(clas_por_run= factor(clas_por_run, levels= c("Ninguno puro", "Desconocido", "Otros reportados (no mapuche)", "Mapuche")))|> 
    arrange(clas_por_run)|>
  mutate(percent= scales::percent(percent, accuracy=.1))
# 1 Ninguno puro                  1161822 91.0%  
# 2 Desconocido                     90256 7.1%   
# 3 Otros reportados (no mapuche)    4170 0.3%   
# 4 Mapuche                         20555 1.6% 

tab_clas_por_run2|>                       # tu data frame
  mutate(
    clas_por_run = case_when(
      # 1. priorizamos Mapuche
      tiene_mapuche ~ "Mapuche",
      # 2. luego otros pueblos originarios distintos de Mapuche
      tiene_otro_po ~ "Otros reportados (no mapuche)",
      # 3. si no hay Mapuche ni otros y se reporta “ninguno”
      tiene_desconocido ~ "Desconocido",
      # 4. si no hay Mapuche ni otros y se reporta “ninguno”
      !tiene_mapuche & !tiene_otro_po & tiene_ninguno ~ "Ninguno puro",
      # 4. cualquier otro caso ⇒ NA
      TRUE ~ NA_character_
    )
  )|> 
  janitor::tabyl(clas_por_run, show_na = TRUE)|> 
  mutate(percent= scales::percent(percent, accuracy=.1))|> mutate(clas_por_run= factor(clas_por_run, levels= c("Ninguno puro", "Desconocido", "Otros reportados (no mapuche)", "Mapuche")))|> 
    arrange(clas_por_run)
# 1 Ninguno puro                  1161822 91.0%  
# 2 Desconocido                     90256 7.1%   
# 3 Otros reportados (no mapuche)    4170 0.3%   
# 4 Mapuche                         20555 1.6%  


#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:
#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:
#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:

cat("Hecho con nuestra base de datos\n")

tab_clas_por_run3 <- 
  df_filled2 |> arrange(run, fecha_ingreso) |> group_by(run) |> slice(1) |> ungroup() |> 
      replace_na(list(
    CyA_Conadi = 0,
    CI_Conadi  = 0,
    RSH        = 0
  ))|> 
   mutate(
    glosa_pueblo_originario_rec = case_when(
      glosa_pueblo_originario == "NINGUNO" &
      (cya_conadi == 1 | ci_conadi == 1 | rsh == 1)~ "DESCONOCIDO",
#        run %in% ppoo_inclusivo[,2]~ "DESCONOCIDO", #esto es porque en alguna oportunidad registro pertenencia
      T~ as.character(glosa_pueblo_originario)   # evita choque factor/chr
    )
  )|> 
  summarise(
    tiene_otro_po     = any(str_detect(glosa_pueblo_originario_rec, regex_otro)),
    tiene_mapuche     = any(str_detect(glosa_pueblo_originario_rec, "MAPUCHE")),
    tiene_ninguno     = any(glosa_pueblo_originario_rec == "NINGUNO"),
    tiene_desconocido = any(glosa_pueblo_originario_rec == "DESCONOCIDO"), # si dejo al final, no recojo ningun "DESCONOCIDO"    
    .by = run)#|>
tab_clas_por_run3|>                       # tu data frame
  mutate(
    clas_por_run = case_when(
      # 1. priorizamos Mapuche
      tiene_mapuche ~ "Mapuche",
      # 2. luego otros pueblos originarios distintos de Mapuche
      tiene_otro_po ~ "Otros reportados (no mapuche)",
      # 3. si no hay Mapuche ni otros y se reporta “ninguno”
      tiene_desconocido ~ "Desconocido",
      # 4. si no hay Mapuche ni otros y se reporta “ninguno”
      !tiene_mapuche & !tiene_otro_po & tiene_ninguno ~ "Ninguno puro",
      # 4. cualquier otro caso ⇒ NA
      TRUE ~ NA_character_
    )
  )|> 
  janitor::tabyl(clas_por_run, show_na = TRUE)|> 
  mutate(clas_por_run= factor(clas_por_run, levels= c("Ninguno puro", "Desconocido", "Otros reportados (no mapuche)", "Mapuche")))|> 
  arrange(clas_por_run)|>
     (\(df) {
  print(mutate(df, percent= scales::percent(percent, accuracy=.1)))
       if (interactive()) {mutate(df, percent=scales::percent(percent, accuracy=.1)) |>  rio::export("clipboard")}
     })()       
# 1 Desconocido                     721 10.9%  
# 2 Mapuche                         143 2.2%   
# 3 Ninguno puro                   5689 85.9%  
# 4 Otros reportados (no mapuche)    73 1.1% 

tab_clas_por_run3|>                       # tu data frame
  mutate(
    clas_por_run = case_when(
      # 1. priorizamos Mapuche
      tiene_mapuche ~ "Mapuche",
      # 2. luego otros pueblos originarios distintos de Mapuche
      tiene_otro_po ~ "Otros reportados (no mapuche)",
      # 3. si no hay Mapuche ni otros y se reporta “ninguno”
      tiene_desconocido ~ "Desconocido",
      # 4. si no hay Mapuche ni otros y se reporta “ninguno”
      !tiene_mapuche & !tiene_otro_po & tiene_ninguno ~ "Ninguno puro",
      # 4. cualquier otro caso ⇒ NA
      TRUE ~ NA_character_
    )
  )|> 
  left_join(ing_dt_ing_calendar_quarter_t_desde_primera_adm_dedup_wide2_cens[,c("run","clus_pam_om4")], by="run", multiple="first")|>
  janitor::tabyl(clas_por_run, clus_pam_om4, show_na = TRUE)|>
   (\(df) {
  print( print(janitor::fisher.test(df, simulate.p.value = T, B = 1e5)))
      mutate(df, clas_por_run= factor(clas_por_run, levels= c("Ninguno puro", "Desconocido", "Otros reportados (no mapuche)", "Mapuche")))|> 
  arrange(clas_por_run)|>
      janitor::adorn_percentages("col")|>  # convierte a proporciones por columna
      janitor::adorn_pct_formatting(digits = 1)|>  # “12.3%”
      janitor::adorn_ns(position = "front")|>  # “12 (34.5%)”
        (\(df2) {
      if (interactive()) {mutate(df2, across(-1, ~ gsub("%", "", gsub("\\.", ",", .))))|> rio::export("clipboard")}
  knitr::kable(df2,caption="Porcentajes por columna, conglomerado vs. PPOO")
        })()
  })()
Aquí ya no se clasifica como Desconocido si hay información en MINSAL sobre autoidentificación, sino solo MIDESO# A tidytable: 4 × 3
  clas_por_run                        n percent
  <fct>                           <int> <chr>  
1 Ninguno puro                  1161822 91.0%  
2 Desconocido                     90256 7.1%   
3 Otros reportados (no mapuche)    4170 0.3%   
4 Mapuche                         20555 1.6%   
# A tidytable: 4 × 3
  clas_por_run                        n percent
  <fct>                           <int> <chr>  
1 Ninguno puro                  1161822 91.0%  
2 Desconocido                     90256 7.1%   
3 Otros reportados (no mapuche)    4170 0.3%   
4 Mapuche                         20555 1.6%   
Hecho con nuestra base de datos
# A tidytable: 4 × 3
  clas_por_run                      n percent
  <fct>                         <int> <chr>  
1 Ninguno puro                   5689 85.9%  
2 Desconocido                     721 10.9%  
3 Otros reportados (no mapuche)    73 1.1%   
4 Mapuche                         143 2.2%   

    Fisher's Exact Test for Count Data with simulated p-value (based on
    1e+05 replicates)

data:  df
p-value = 0.07162
alternative hypothesis: two.sided


    Fisher's Exact Test for Count Data with simulated p-value (based on
    1e+05 replicates)

data:  df
p-value = 0.07162
alternative hypothesis: two.sided
Porcentajes por columna, conglomerado vs. PPOO
clas_por_run 6623, Un trimestre, TSM(4) 6612, Un trimestre, TUS(3) 6522, Un semestre TSM(1) 6574, Comorbilidad un trimestre(2)
Ninguno puro 4,521 (86.1%) 622 (82.9%) 344 (86.2%) 202 (88.2%)
Desconocido 558 (10.6%) 103 (13.7%) 39 (9.8%) 21 (9.2%)
Otros reportados (no mapuche) 61 (1.2%) 3 (0.4%) 7 (1.8%) 2 (0.9%)
Mapuche 108 (2.1%) 22 (2.9%) 9 (2.3%) 4 (1.7%)

Tiempo que demora esta sección: 0.7 minutos

EXTRA2. Post rev internas. Comparación pertenencia amplia, BBDD 2018 general

Código
cat("Hacemos una clasificación comparable a la versión autorreportada de PPOO MINSAL pero para todos las hospitalizaciones del 2018")
cat("Traemos la base de datos con todos los clasificados como PPOO\n")
filtered_df_csv <- readr::read_csv("filtered_df.csv", col_types = readr::cols(...1 = readr::col_skip()), skip=1)
colnames(filtered_df_csv)<- c("run")

nrow(filtered_df_csv)
#[1] 1687190
ci_cya_conadi<-readr::read_csv("cya_conadi_o_ci_conadi.csv")
nrow(ci_cya_conadi)
#[1] 1037607
nrow(unique(ci_cya_conadi))
#[1] 476338

cat("Whatever PPOO identification")
scales::percent(nrow(filtered_df_csv)/9646325, accuracy=.1)
#[1] "17.5%"


cat("Y si veo del 2018 en adelante con todas las hospitalizaciones en ese periodo\n")
  data_nueva|> 
  filter(FECHA_INGRESO_FMT_DEIS >= as.Date("2018-01-01"), FECHA_INGRESO_FMT_DEIS < as.Date("2019-01-01"))|> 
          (\(df) {
            nrow(distinct(df, RUN))->> filt_data_nueva
            df
            })() |> 
    filter(RUN %in% pull(filtered_df_csv))|> 
    distinct(RUN) |> 
      (\(df) {
      print(paste0("Sólo PPOO que tienen CUALQUIERA (RSH/MINSAL histórico O CONADIS): ",nrow(df)))
      print(paste0("Sólo PPOO que tienen CUALQUIERA (RSH/MINSAL histórico O CONADIS) %: ",scales::percent(nrow(df)/filt_data_nueva, accuracy=.1)))
  })()


cat("Institutional recognition")
scales::percent(nrow(unique(ci_cya_conadi))/nrow(distinct(data_nueva, RUN)), accuracy=.1)
#[1] "4.9%"


#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:
cat("Quienes tienen ambos (divide por el total de pacientes históricos)\n")
filtered_df_csv |> 
  tidytable::inner_join(ci_cya_conadi, by=c("run"="RUN"), multiple="first") |> 
  nrow()
#[1] 800271
scales::percent(800271/9646325, accuracy=.1)


#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:
cat("Y si veo del 2018 en adelante con todas las hospitalizaciones en ese periodo\n")
  data_nueva|> 
  filter(FECHA_INGRESO_FMT_DEIS >= as.Date("2018-01-01"), FECHA_INGRESO_FMT_DEIS < as.Date("2019-01-01"))|> 
          (\(df) {
            nrow(distinct(df, RUN))->> filt_data_nueva
            df
            })() |> 
    filter(RUN %in% pull(tidytable::inner_join(filtered_df_csv, ci_cya_conadi, by=c("run"="RUN"), multiple="first"),run))|> 
    distinct(RUN) |> 
      (\(df) {
      print(paste0("Sólo PPOO que tienen ambos (RSH/MINSAL histórico + CONADIS): ",nrow(df)))
      print(paste0("Sólo PPOO que tienen ambos (RSH/MINSAL histórico + CONADIS) %: ",scales::percent(nrow(df)/filt_data_nueva, accuracy=.1)))
  })()
  # [1] "Sólo PPOO pero inclusivo (cualquiera): 46704"
  # [1] "Sólo PPOO pero inclusivo (cualquiera) %: 3.7%"

#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:
#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:
cat("Sólo CONADI\n")
cbind.data.frame(filtered_df_csv, rn=1:length(ci_cya_conadi)) |> 
  tidytable::right_join(ci_cya_conadi, by=c("run"="RUN"), multiple="first") |> 
  filter(is.na(rn)) |> 
  nrow()

cbind.data.frame(ci_cya_conadi, rn_conadi=1:length(ci_cya_conadi$RUN))|> 
  tidytable::left_join(cbind.data.frame(filtered_df_csv, rn=1:length(filtered_df_csv$run)), by=c("RUN"="run"), multiple="first") |> 
  filter(is.na(rn)) |> 
  nrow()
#[1] 237336
scales::percent(237336/9646325, accuracy=.1)

cat("Y si veo del 2018 en adelante con todas las hospitalizaciones en ese periodo\n")
  data_nueva|> 
  filter(FECHA_INGRESO_FMT_DEIS >= as.Date("2018-01-01"), FECHA_INGRESO_FMT_DEIS < as.Date("2019-01-01"))|> 
          (\(df) {
            nrow(distinct(df, RUN))->> filt_data_nueva
            df
            })() |> 
  filter(RUN %in% pull(
    cbind.data.frame(ci_cya_conadi, rn_conadi=1:length(ci_cya_conadi$RUN))|> 
  tidytable::left_join(cbind.data.frame(filtered_df_csv, rn=1:length(filtered_df_csv$run)), by=c("RUN"="run"), multiple="first") |> 
  filter(is.na(rn)), RUN))|> 
    distinct(RUN) |> 
      (\(df) {
      print(paste0("Sólo PPOO CONADI: ",nrow(df)))
      print(paste0("Sólo PPOO CONADI %: ",scales::percent(nrow(df)/filt_data_nueva, accuracy=.1)))
  })()
  # [1] "Solo CONADI: 14945"
  # [1] "Solo CONADI %: 1.2%"

  #:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:
#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:#:
cat("Sólo RSH o autodentificación histórico\n")
cbind.data.frame(filtered_df_csv, rn=1:length(filtered_df_csv$run)) |> 
  tidytable::left_join(cbind.data.frame(ci_cya_conadi, rn_conadi=1:length(ci_cya_conadi$RUN)), by=c("run"="RUN"), multiple="first") |> 
  filter(is.na(rn_conadi)) |> 
  nrow()
#[1] 1329383
scales::percent(1329383/9646325, accuracy=.1)
#13.8

cat("Y si veo del 2018 en adelante con todas las hospitalizaciones en ese periodo\n")
  data_nueva|>
  filter(FECHA_INGRESO_FMT_DEIS >= as.Date("2018-01-01"), FECHA_INGRESO_FMT_DEIS < as.Date("2019-01-01"))|> 
          (\(df) {
            nrow(distinct(df, RUN))->> filt_data_nueva
            df
            })() |> 
  filter(RUN %in% pull(
      cbind.data.frame(filtered_df_csv, rn=1:length(filtered_df_csv$run)) |> 
    tidytable::left_join(cbind.data.frame(ci_cya_conadi, rn_conadi=1:length(ci_cya_conadi$RUN)), by=c("run"="RUN"), multiple="first") |> 
    filter(is.na(rn_conadi)), run)
    ) |> 
    distinct(RUN) |> 
      (\(df) {
      print(paste0("Sólo RSH o autoidentificación histórico: ",nrow(df)))
      print(paste0("Sólo RSH o autoidentificación histórico %: ",scales::percent(nrow(df)/filt_data_nueva, accuracy=.1)))
  })()
# [1] "Sólo RSH o autoidentificación histórico: 151089"
# [1] "Sólo RSH o autoidentificación histórico %: 11.8%"
  
  
  
invisible("19.9% of the patients were identified as belonging to an Indigenous Peoples group in any hospital record since 2005 or in the Social household register file (17.8%) or were officially recognized as such in the Registry of  Indigenous Status/Communities (8.5%).")  
rm(data_nueva)
rm(ci_cya_conadi)
rm(filtered_df_csv)
Hacemos una clasificación comparable a la versión autorreportada de PPOO MINSAL pero para todos las hospitalizaciones del 2018Traemos la base de datos con todos los clasificados como PPOO
[1] 1687189
[1] 1037607
[1] 476338
Whatever PPOO identification[1] "17.5%"
Y si veo del 2018 en adelante con todas las hospitalizaciones en ese periodo
[1] "Sólo PPOO que tienen CUALQUIERA (RSH/MINSAL histórico O CONADIS): 197793"
[1] "Sólo PPOO que tienen CUALQUIERA (RSH/MINSAL histórico O CONADIS) %: 15.5%"
Institutional recognition[1] "4.9%"
Quienes tienen ambos (divide por el total de pacientes históricos)
[1] 800271
[1] "8.3%"
Y si veo del 2018 en adelante con todas las hospitalizaciones en ese periodo
[1] "Sólo PPOO que tienen ambos (RSH/MINSAL histórico + CONADIS): 46704"
[1] "Sólo PPOO que tienen ambos (RSH/MINSAL histórico + CONADIS) %: 3.7%"
Sólo CONADI
[1] 237336
[1] 237336
[1] "2.5%"
Y si veo del 2018 en adelante con todas las hospitalizaciones en ese periodo
[1] "Sólo PPOO CONADI: 14945"
[1] "Sólo PPOO CONADI %: 1.2%"
Sólo RSH o autodentificación histórico
[1] 1329383
[1] "13.8%"
Y si veo del 2018 en adelante con todas las hospitalizaciones en ese periodo
[1] "Sólo RSH o autoidentificación histórico: 151089"
[1] "Sólo RSH o autoidentificación histórico %: 11.8%"

Tiempo que demora esta sección: 0.3 minutos


Información de la sesión

Código
message(paste0("R library: ", Sys.getenv("R_LIBS_USER")))

R library: C:/R/win-library/4.4

Código
message(paste0("Date: ",withr::with_locale(new = c('LC_TIME' = 'C'), code =Sys.time())))

Date: 2025-05-19 10:02:52.680867

Código
message(paste0("Editor context: ", getwd()))

Editor context: H:/My Drive/PERSONAL ANDRES/UCH_salud_publica/asignaturas/un_inv_II

Código
cat("\nquarto version: "); system("quarto --version") 

quarto version: 
[1] 0
Código
save.image("avance250117_25.RData")

Tiempo que demora esta sección: 0.8 minutos

Código
sesion_info <- devtools::session_info()

Warning in system2(“quarto”, “-V”, stdout = TRUE, env = paste0(“TMPDIR=”, : el comando ejecutado ‘“quarto” TMPDIR=C:/Users/andre/AppData/Local/Temp/Rtmpkl0VC9/file1912c52dd591a -V’ tiene el estatus 1

Código
dplyr::select(
  tibble::as_tibble(sesion_info$packages),
  c(package, loadedversion, source)
) |> 
 knitr::kable(caption = "R packages", format = "html",
      col.names = c("Row number", "Package", "Version"),
    row.names = FALSE,
      align = c("c", "l", "r")) |> 
  kableExtra::kable_styling(bootstrap_options = c("striped", "hover"),font_size = 12) |> 
  kableExtra::scroll_box(width = "100%", height = "375px")  
R packages
Row number Package Version
abind 1.4-8 CRAN (R 4.4.1)
backports 1.5.0 CRAN (R 4.4.1)
biostat3 0.2.2 CRAN (R 4.4.3)
bit 4.6.0 CRAN (R 4.4.1)
bit64 4.6.0-1 CRAN (R 4.4.1)
boot 1.3-31 CRAN (R 4.4.1)
broom 1.0.7 CRAN (R 4.4.1)
cachem 1.1.0 CRAN (R 4.4.1)
car 3.1-3 CRAN (R 4.4.1)
carData 3.0-5 CRAN (R 4.4.1)
chisq.posthoc.test 0.1.3 Github (ebbertd/chisq.posthoc.test@186d2ca6bbdba9fc19601aff4696ae1b85e7e0b0)
cli 3.6.4 CRAN (R 4.4.1)
cluster 2.1.8.1 CRAN (R 4.4.1)
coda 0.19-4.1 CRAN (R 4.4.1)
codetools 0.2-20 CRAN (R 4.4.1)
colorspace 2.1-1 CRAN (R 4.4.1)
cowplot 1.1.3 CRAN (R 4.4.1)
crayon 1.5.3 CRAN (R 4.4.1)
curl 6.2.1 CRAN (R 4.4.1)
data.table 1.17.0 CRAN (R 4.4.1)
devtools 2.4.5 CRAN (R 4.4.1)
DiagrammeR 1.0.11 CRAN (R 4.4.1)
DiagrammeRsvg 0.1 CRAN (R 4.4.1)
digest 0.6.37 CRAN (R 4.4.1)
doFuture 1.0.1 CRAN (R 4.4.1)
doParallel 1.0.17 CRAN (R 4.4.1)
dplyr 1.1.4 CRAN (R 4.4.3)
ellipsis 0.3.2 CRAN (R 4.4.1)
emmeans 1.11.0 CRAN (R 4.4.3)
epitools 0.5-10.1 CRAN (R 4.4.0)
estimability 1.5.1 CRAN (R 4.4.1)
evaluate 1.0.3 CRAN (R 4.4.1)
expsmooth 2.3 CRAN (R 4.4.3)
factoextra 1.0.7 CRAN (R 4.4.1)
farver 2.1.2 CRAN (R 4.4.1)
fastcluster 1.2.6 CRAN (R 4.4.1)
fastmap 1.2.0 CRAN (R 4.4.1)
fma 2.5 CRAN (R 4.4.3)
forcats 1.0.0 CRAN (R 4.4.1)
foreach 1.5.2 CRAN (R 4.4.1)
forecast 8.24.0 CRAN (R 4.4.3)
Formula 1.2-5 CRAN (R 4.4.1)
fpp2 2.5 CRAN (R 4.4.3)
fracdiff 1.5-3 CRAN (R 4.4.1)
fs 1.6.5 CRAN (R 4.4.1)
future 1.34.0 CRAN (R 4.4.1)
future.apply 1.11.3 CRAN (R 4.4.1)
generics 0.1.3 CRAN (R 4.4.1)
ggh4x 0.3.0 CRAN (R 4.4.1)
ggplot2 3.5.2 CRAN (R 4.4.3)
ggpubr 0.6.0 CRAN (R 4.4.1)
ggrepel 0.9.6 CRAN (R 4.4.1)
ggseqplot 0.8.5 CRAN (R 4.4.1)
ggsignif 0.6.4 CRAN (R 4.4.1)
globals 0.16.3 CRAN (R 4.4.1)
glue 1.8.0 CRAN (R 4.4.1)
gridExtra 2.3 CRAN (R 4.4.1)
gtable 0.3.6 CRAN (R 4.4.1)
gtsummary 2.2.0 CRAN (R 4.4.3)
haven 2.5.4 CRAN (R 4.4.1)
hms 1.1.3 CRAN (R 4.4.1)
htmltools 0.5.8.1 CRAN (R 4.4.1)
htmlwidgets 1.6.4 CRAN (R 4.4.1)
httpuv 1.6.15 CRAN (R 4.4.1)
iterators 1.0.14 CRAN (R 4.4.1)
janitor 2.2.1 CRAN (R 4.4.1)
job 0.3.1 CRAN (R 4.4.1)
jsonlite 1.9.1 CRAN (R 4.4.1)
kableExtra 1.4.0 CRAN (R 4.4.1)
km.ci 0.5-6 CRAN (R 4.4.3)
KMsurv 0.1-5 CRAN (R 4.4.0)
knitr 1.49 CRAN (R 4.4.1)
labeling 0.4.3 CRAN (R 4.4.1)
later 1.4.1 CRAN (R 4.4.1)
lattice 0.22-6 CRAN (R 4.4.1)
lifecycle 1.0.4 CRAN (R 4.4.1)
listenv 0.9.1 CRAN (R 4.4.1)
lmtest 0.9-40 CRAN (R 4.4.1)
lubridate 1.9.4 CRAN (R 4.4.1)
magrittr 2.0.3 CRAN (R 4.4.1)
MASS 7.3-60.2 CRAN (R 4.4.1)
mathjaxr 1.8-0 CRAN (R 4.4.3)
Matrix 1.7-0 CRAN (R 4.4.1)
memoise 2.0.1 CRAN (R 4.4.1)
metadat 1.4-0 CRAN (R 4.4.3)
metafor 4.8-0 CRAN (R 4.4.3)
mgcv 1.9-1 CRAN (R 4.4.1)
mime 0.12 CRAN (R 4.4.1)
miniUI 0.1.1.1 CRAN (R 4.4.1)
mnormt 2.1.1 CRAN (R 4.4.1)
multcomp 1.4-28 CRAN (R 4.4.1)
munsell 0.5.1 CRAN (R 4.4.1)
mvtnorm 1.3-3 CRAN (R 4.4.1)
NbClust 3.0.1 CRAN (R 4.4.1)
nlme 3.1-164 CRAN (R 4.4.1)
nnet 7.3-19 CRAN (R 4.4.1)
numDeriv 2016.8-1.1 CRAN (R 4.4.1)
pacman 0.5.1 CRAN (R 4.4.3)
parallelly 1.42.0 CRAN (R 4.4.1)
patchwork 1.3.0 CRAN (R 4.4.1)
permute 0.9-7 CRAN (R 4.4.1)
pillar 1.10.1 CRAN (R 4.4.1)
pkgbuild 1.4.6 CRAN (R 4.4.1)
pkgconfig 2.0.3 CRAN (R 4.4.1)
pkgload 1.4.0 CRAN (R 4.4.1)
plyr 1.8.9 CRAN (R 4.4.1)
profvis 0.4.0 CRAN (R 4.4.1)
progressr 0.15.1 CRAN (R 4.4.1)
promises 1.3.2 CRAN (R 4.4.1)
psych 2.4.12 CRAN (R 4.4.1)
purrr 1.0.4 CRAN (R 4.4.1)
quadprog 1.5-8 CRAN (R 4.4.1)
quantmod 0.4.26 CRAN (R 4.4.1)
R.methodsS3 1.8.2 CRAN (R 4.4.1)
R.oo 1.27.0 CRAN (R 4.4.1)
R.utils 2.13.0 CRAN (R 4.4.1)
R6 2.6.1 CRAN (R 4.4.1)
ragg 1.3.3 CRAN (R 4.4.1)
rbibutils 2.3 CRAN (R 4.4.1)
RColorBrewer 1.1-3 CRAN (R 4.4.0)
Rcpp 1.0.14 CRAN (R 4.4.1)
Rdpack 2.6.2 CRAN (R 4.4.1)
readr 2.1.5 CRAN (R 4.4.3)
remotes 2.5.0 CRAN (R 4.4.1)
reshape2 1.4.4 CRAN (R 4.4.1)
rio 1.2.3 CRAN (R 4.4.1)
rlang 1.1.5 CRAN (R 4.4.1)
rmarkdown 2.29 CRAN (R 4.4.1)
rstatix 0.7.2 CRAN (R 4.4.1)
rstudioapi 0.17.1 CRAN (R 4.4.1)
rsvg 2.6.2 CRAN (R 4.4.3)
sandwich 3.1-1 CRAN (R 4.4.1)
scales 1.3.0 CRAN (R 4.4.1)
sessioninfo 1.2.3 CRAN (R 4.4.1)
shiny 1.10.0 CRAN (R 4.4.1)
snakecase 0.11.1 CRAN (R 4.4.1)
stargazer 5.2.3 CRAN (R 4.4.1)
stringi 1.8.4 CRAN (R 4.4.1)
stringr 1.5.1 CRAN (R 4.4.3)
survival 3.6-4 CRAN (R 4.4.1)
survminer 0.5.0 CRAN (R 4.4.3)
survMisc 0.5.6 CRAN (R 4.4.3)
svglite 2.1.3 CRAN (R 4.4.1)
systemfonts 1.2.1 CRAN (R 4.4.1)
textshaping 1.0.0 CRAN (R 4.4.1)
TH.data 1.1-3 CRAN (R 4.4.1)
tibble 3.2.1 CRAN (R 4.4.1)
tidyr 1.3.1 CRAN (R 4.4.1)
tidyselect 1.2.1 CRAN (R 4.4.1)
tidytable 0.11.2 CRAN (R 4.4.1)
tidyverse 2.0.0 CRAN (R 4.4.3)
timechange 0.3.0 CRAN (R 4.4.1)
timeDate 4041.110 CRAN (R 4.4.1)
Tmisc 1.0.1 CRAN (R 4.4.1)
TraMineR 2.2-11 CRAN (R 4.4.1)
TraMineRextras 0.6.8 CRAN (R 4.4.1)
tseries 0.10-58 CRAN (R 4.4.1)
TTR 0.24.4 CRAN (R 4.4.1)
tzdb 0.4.0 CRAN (R 4.4.1)
urca 1.3-4 CRAN (R 4.4.1)
urlchecker 1.0.1 CRAN (R 4.4.1)
usethis 3.1.0 CRAN (R 4.4.1)
utf8 1.2.4 CRAN (R 4.4.1)
V8 6.0.1 CRAN (R 4.4.1)
vctrs 0.6.5 CRAN (R 4.4.1)
vegan 2.6-10 CRAN (R 4.4.1)
vegclust 2.0.2 CRAN (R 4.4.1)
viridisLite 0.4.2 CRAN (R 4.4.1)
visNetwork 2.1.2 CRAN (R 4.4.1)
vroom 1.6.5 CRAN (R 4.4.1)
WeightedCluster 1.8-1 CRAN (R 4.4.1)
withr 3.0.2 CRAN (R 4.4.1)
writexl 1.5.1 CRAN (R 4.4.1)
xfun 0.51 CRAN (R 4.4.1)
xml2 1.3.7 CRAN (R 4.4.1)
xtable 1.8-4 CRAN (R 4.4.1)
xts 0.14.1 CRAN (R 4.4.1)
yaml 2.3.10 CRAN (R 4.4.1)
zoo 1.8-13 CRAN (R 4.4.1)

Tiempo que demora esta sección: 0 minutos

Código
reticulate::py_list_packages()|> 
 knitr::kable(caption = "Python packages", format = "html",
      col.names = c("Package", "Version", "Requirement"),
    row.names = FALSE,
      align = c("c", "l", "r", "r"))|> 
  kableExtra::kable_styling(bootstrap_options = c("striped", "hover"),font_size = 12) |> 
  kableExtra::scroll_box(width = "100%", height = "375px")  

Error in path.expand(path): argumento ‘path’ inválido

Tiempo que demora esta sección: 0 minutos